Browse Source

Start building the TreeView.

pull/1/head
Daniel Grunwald 15 years ago
parent
commit
d84bc42d06
  1. 24
      ILSpy.sln
  2. 8
      ILSpy/App.xaml
  3. 105
      ILSpy/AssemblyTreeNode.cs
  4. 20
      ILSpy/ILSpy.csproj
  5. BIN
      ILSpy/Images/Assembly.png
  6. 55
      ILSpy/Images/Images.cs
  7. 17
      ILSpy/MainWindow.xaml
  8. 24
      ILSpy/MainWindow.xaml.cs
  9. 426
      ILSpy/Mono.Cecil.Rocks/MethodBodyRocks.cs
  10. 33
      ILSpy/NamespaceTreeNode.cs
  11. 97
      ILSpy/TreeTraversal.cs
  12. 132
      ILSpy/TypeTreeNode.cs

24
ILSpy.sln

@ -1,18 +1,40 @@ @@ -1,18 +1,40 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.0.1.7084
# SharpDevelop 4.0.1.7088
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy", "ILSpy\ILSpy.csproj", "{1E85EFF9-E370-4683-83E4-8A3D063FF791}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TreeView", "SharpTreeView\ICSharpCode.TreeView.csproj", "{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "Mono.Cecil\Mono.Cecil.csproj", "{D68133BD-1E63-496E-9EDE-4FBDBF77B486}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.Build.0 = Debug|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|x86.ActiveCfg = Debug|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|x86.Build.0 = Release|x86
{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|x86.ActiveCfg = Release|x86
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|x86.Build.0 = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|x86.Build.0 = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|x86.ActiveCfg = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|Any CPU.Build.0 = Release|Any CPU
{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.ActiveCfg = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.ActiveCfg = net_2_0_Debug|Any CPU
EndGlobalSection
EndGlobal

8
ILSpy/App.xaml

@ -1,8 +1,12 @@ @@ -1,8 +1,12 @@
<Application x:Class="ICSharpCode.ILSpy.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="DialogWindow" TargetType="{x:Type Window}">
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
</Style>
</Application.Resources>
</Application>

105
ILSpy/AssemblyTreeNode.cs

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
sealed class AssemblyTreeNode : SharpTreeNode
{
readonly AssemblyDefinition assembly;
readonly List<TypeTreeNode> classes = new List<TypeTreeNode>();
public ObservableCollection<NamespaceTreeNode> Namespaces { get; private set; }
readonly Dictionary<TypeDefinition, TypeTreeNode> typeDict = new Dictionary<TypeDefinition, TypeTreeNode>();
readonly Dictionary<string, NamespaceTreeNode> namespaces = new Dictionary<string, NamespaceTreeNode>();
public AssemblyTreeNode(AssemblyDefinition assembly)
{
if (assembly == null)
throw new ArgumentNullException("assembly");
this.assembly = assembly;
this.Namespaces = new ObservableCollection<NamespaceTreeNode>();
InitClassList();
BuildNestedTypeLists();
BuildNamespaceList();
}
public override object Text {
get { return assembly.Name.Name; }
}
public override object Icon {
get { return Images.Assembly; }
}
void InitClassList()
{
foreach (TypeDefinition type in assembly.MainModule.Types.OrderBy(t => t.FullName)) {
var viewmodel = new TypeTreeNode(type);
typeDict.Add(type, viewmodel);
if (type.IsNested == false) {
classes.Add(viewmodel);
}
foreach (TypeDefinition nestedType in TreeTraversal.PreOrder(type.NestedTypes, t => t.NestedTypes)) {
typeDict.Add(nestedType, new TypeTreeNode(nestedType));
}
}
}
void BuildNestedTypeLists()
{
foreach (var typeModel in typeDict.Values) {
typeModel.NestedTypes.Clear();
}
foreach (var pair in typeDict) {
if (showInternalAPI == false && pair.Value.IsPublicAPI == false)
continue;
if (pair.Key.IsNested) {
typeDict[pair.Key.DeclaringType].NestedTypes.Add(pair.Value);
}
}
}
void BuildNamespaceList()
{
this.Children.Clear();
foreach (NamespaceTreeNode ns in namespaces.Values) {
ns.Children.Clear();
}
foreach (TypeTreeNode type in classes) {
if (showInternalAPI == false && type.IsPublicAPI == false)
continue;
NamespaceTreeNode ns;
if (!namespaces.TryGetValue(type.Namespace, out ns)) {
ns = new NamespaceTreeNode(type.Namespace);
namespaces[type.Namespace] = ns;
}
ns.Children.Add(type);
}
foreach (NamespaceTreeNode ns in namespaces.Values.OrderBy(n => n.Name)) {
if (ns.Children.Count > 0)
this.Children.Add(ns);
}
}
bool showInternalAPI;
public bool ShowInternalAPI {
get { return showInternalAPI; }
set {
if (showInternalAPI != value) {
showInternalAPI = value;
BuildNestedTypeLists();
BuildNamespaceList();
RaisePropertyChanged("ShowInternalAPI");
}
}
}
}
}

20
ILSpy/ILSpy.csproj

@ -64,13 +64,18 @@ @@ -64,13 +64,18 @@
<SubType>Code</SubType>
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Images\TypeImages.cs" />
<Compile Include="AssemblyTreeNode.cs" />
<Compile Include="Images\Images.cs" />
<Compile Include="Mono.Cecil.Rocks\MethodBodyRocks.cs" />
<Compile Include="NamespaceTreeNode.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\WPFAssemblyInfo.cs" />
<Compile Include="MainWindow.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Compile Include="TreeTraversal.cs" />
<Compile Include="TypeTreeNode.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="MainWindow.xaml" />
@ -106,11 +111,22 @@ @@ -106,11 +111,22 @@
<Resource Include="Images\ProtectedInterface.png" />
<Resource Include="Images\ProtectedMethod.png" />
<Resource Include="Images\ProtectedStruct.png" />
<Resource Include="Images\Reference.png" />
<Resource Include="Images\Assembly.png" />
<Resource Include="Images\Struct.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="Images" />
<Folder Include="Mono.Cecil.Rocks" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.Cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj">
<Project>{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}</Project>
<Name>ICSharpCode.TreeView</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

BIN
ILSpy/Images/Assembly.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

55
ILSpy/Images/Images.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Windows.Media.Imaging;
namespace ICSharpCode.ILSpy
{
static class Images
{
static BitmapImage LoadBitmap(string name)
{
BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/Images/" + name + ".png"));
image.Freeze();
return image;
}
public static readonly BitmapImage Assembly = LoadBitmap("Assembly");
public static readonly BitmapImage Namespace = LoadBitmap("NameSpace");
public static readonly BitmapImage Class = LoadBitmap("Class");
public static readonly BitmapImage Delegate = LoadBitmap("Delegate");
public static readonly BitmapImage Enum = LoadBitmap("Enum");
public static readonly BitmapImage Interface = LoadBitmap("Interface");
public static readonly BitmapImage Struct = LoadBitmap("Struct");
public static readonly BitmapImage Field = LoadBitmap("Field");
public static readonly BitmapImage Method = LoadBitmap("Method");
public static readonly BitmapImage Literal = LoadBitmap("Literal");
public static readonly BitmapImage InternalClass = LoadBitmap("InternalClass");
public static readonly BitmapImage InternalDelegate = LoadBitmap("InternalDelegate");
public static readonly BitmapImage InternalEnum = LoadBitmap("InternalEnum");
public static readonly BitmapImage InternalInterface = LoadBitmap("InternalInterface");
public static readonly BitmapImage InternalStruct = LoadBitmap("InternalStruct");
public static readonly BitmapImage InternalField = LoadBitmap("InternalField");
public static readonly BitmapImage InternalMethod = LoadBitmap("InternalMethod");
public static readonly BitmapImage PrivateClass = LoadBitmap("PrivateClass");
public static readonly BitmapImage PrivateDelegate = LoadBitmap("PrivateDelegate");
public static readonly BitmapImage PrivateEnum = LoadBitmap("PrivateEnum");
public static readonly BitmapImage PrivateInterface = LoadBitmap("PrivateInterface");
public static readonly BitmapImage PrivateStruct = LoadBitmap("PrivateStruct");
public static readonly BitmapImage PrivateField = LoadBitmap("PrivateField");
public static readonly BitmapImage PrivateMethod = LoadBitmap("PrivateMethod");
public static readonly BitmapImage ProtectedClass = LoadBitmap("ProtectedClass");
public static readonly BitmapImage ProtectedDelegate = LoadBitmap("ProtectedDelegate");
public static readonly BitmapImage ProtectedEnum = LoadBitmap("ProtectedEnum");
public static readonly BitmapImage ProtectedInterface = LoadBitmap("ProtectedInterface");
public static readonly BitmapImage ProtectedStruct = LoadBitmap("ProtectedStruct");
public static readonly BitmapImage ProtectedField = LoadBitmap("ProtectedField");
public static readonly BitmapImage ProtectedMethod = LoadBitmap("ProtectedMethod");
}
}

17
ILSpy/MainWindow.xaml

@ -1,9 +1,16 @@ @@ -1,9 +1,16 @@
<Window x:Class="ICSharpCode.ILSpy.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ILSpy" Height="300" Width="300"
>
<Grid>
</Grid>
xmlns:tv="http://icsharpcode.net/sharpdevelop/treeview"
Title="ILSpy"
Width="790"
Height="500"
MinWidth="250"
MinHeight="200"
UseLayoutRounding="True"
Hyperlink.RequestNavigate="Window_RequestNavigate"
TextOptions.TextFormattingMode="Display"
>
<tv:SharpTreeView Name="treeView" ShowRoot="False" AllowDropOrder="True">
</tv:SharpTreeView>
</Window>

24
ILSpy/MainWindow.xaml.cs

@ -2,25 +2,33 @@ @@ -2,25 +2,33 @@
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Interaction logic for Window1.xaml
/// The main window of the application.
/// </summary>
public partial class MainWindow : Window
{
SharpTreeNodeCollection assemblies;
public MainWindow()
{
InitializeComponent();
treeView.Root = new SharpTreeNode();
assemblies = treeView.Root.Children;
assemblies.Add(new AssemblyTreeNode(AssemblyDefinition.ReadAssembly(typeof(object).Assembly.Location)));
}
void Window_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
}
}
}

426
ILSpy/Mono.Cecil.Rocks/MethodBodyRocks.cs

@ -0,0 +1,426 @@ @@ -0,0 +1,426 @@
//
// MethodBodyRocks.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2010 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using Mono.Cecil.Cil;
namespace Mono.Cecil.Rocks {
#if INSIDE_ROCKS
public
#endif
static class MethodBodyRocks {
public static ParameterDefinition GetParameter (this MethodBody self, int index)
{
var method = self.Method;
if (method.HasThis) {
if (index == 0)
return self.ThisParameter;
index--;
}
var parameters = method.Parameters;
if (index < 0 || index >= parameters.Count)
return null;
return parameters [index];
}
public static void SimplifyMacros (this MethodBody self)
{
if (self == null)
throw new ArgumentNullException ("self");
foreach (var instruction in self.Instructions) {
if (instruction.OpCode.OpCodeType != OpCodeType.Macro)
continue;
switch (instruction.OpCode.Code) {
case Code.Ldarg_0:
ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (0));
break;
case Code.Ldarg_1:
ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (1));
break;
case Code.Ldarg_2:
ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (2));
break;
case Code.Ldarg_3:
ExpandMacro (instruction, OpCodes.Ldarg, self.GetParameter (3));
break;
case Code.Ldloc_0:
ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [0]);
break;
case Code.Ldloc_1:
ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [1]);
break;
case Code.Ldloc_2:
ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [2]);
break;
case Code.Ldloc_3:
ExpandMacro (instruction, OpCodes.Ldloc, self.Variables [3]);
break;
case Code.Stloc_0:
ExpandMacro (instruction, OpCodes.Stloc, self.Variables [0]);
break;
case Code.Stloc_1:
ExpandMacro (instruction, OpCodes.Stloc, self.Variables [1]);
break;
case Code.Stloc_2:
ExpandMacro (instruction, OpCodes.Stloc, self.Variables [2]);
break;
case Code.Stloc_3:
ExpandMacro (instruction, OpCodes.Stloc, self.Variables [3]);
break;
case Code.Ldarg_S:
instruction.OpCode = OpCodes.Ldarg;
break;
case Code.Ldarga_S:
instruction.OpCode = OpCodes.Ldarga;
break;
case Code.Starg_S:
instruction.OpCode = OpCodes.Starg;
break;
case Code.Ldloc_S:
instruction.OpCode = OpCodes.Ldloc;
break;
case Code.Ldloca_S:
instruction.OpCode = OpCodes.Ldloca;
break;
case Code.Stloc_S:
instruction.OpCode = OpCodes.Stloc;
break;
case Code.Ldc_I4_M1:
ExpandMacro (instruction, OpCodes.Ldc_I4, -1);
break;
case Code.Ldc_I4_0:
ExpandMacro (instruction, OpCodes.Ldc_I4, 0);
break;
case Code.Ldc_I4_1:
ExpandMacro (instruction, OpCodes.Ldc_I4, 1);
break;
case Code.Ldc_I4_2:
ExpandMacro (instruction, OpCodes.Ldc_I4, 2);
break;
case Code.Ldc_I4_3:
ExpandMacro (instruction, OpCodes.Ldc_I4, 3);
break;
case Code.Ldc_I4_4:
ExpandMacro (instruction, OpCodes.Ldc_I4, 4);
break;
case Code.Ldc_I4_5:
ExpandMacro (instruction, OpCodes.Ldc_I4, 5);
break;
case Code.Ldc_I4_6:
ExpandMacro (instruction, OpCodes.Ldc_I4, 6);
break;
case Code.Ldc_I4_7:
ExpandMacro (instruction, OpCodes.Ldc_I4, 7);
break;
case Code.Ldc_I4_8:
ExpandMacro (instruction, OpCodes.Ldc_I4, 8);
break;
case Code.Ldc_I4_S:
ExpandMacro (instruction, OpCodes.Ldc_I4, (int) (sbyte) instruction.Operand);
break;
case Code.Br_S:
instruction.OpCode = OpCodes.Br;
break;
case Code.Brfalse_S:
instruction.OpCode = OpCodes.Brfalse;
break;
case Code.Brtrue_S:
instruction.OpCode = OpCodes.Brtrue;
break;
case Code.Beq_S:
instruction.OpCode = OpCodes.Beq;
break;
case Code.Bge_S:
instruction.OpCode = OpCodes.Bge;
break;
case Code.Bgt_S:
instruction.OpCode = OpCodes.Bgt;
break;
case Code.Ble_S:
instruction.OpCode = OpCodes.Ble;
break;
case Code.Blt_S:
instruction.OpCode = OpCodes.Blt;
break;
case Code.Bne_Un_S:
instruction.OpCode = OpCodes.Bne_Un;
break;
case Code.Bge_Un_S:
instruction.OpCode = OpCodes.Bge_Un;
break;
case Code.Bgt_Un_S:
instruction.OpCode = OpCodes.Bgt_Un;
break;
case Code.Ble_Un_S:
instruction.OpCode = OpCodes.Ble_Un;
break;
case Code.Blt_Un_S:
instruction.OpCode = OpCodes.Blt_Un;
break;
case Code.Leave_S:
instruction.OpCode = OpCodes.Leave;
break;
}
}
}
static void ExpandMacro (Instruction instruction, OpCode opcode, object operand)
{
instruction.OpCode = opcode;
instruction.Operand = operand;
}
static void MakeMacro (Instruction instruction, OpCode opcode)
{
instruction.OpCode = opcode;
instruction.Operand = null;
}
public static void OptimizeMacros (this MethodBody self)
{
if (self == null)
throw new ArgumentNullException ("self");
var method = self.Method;
foreach (var instruction in self.Instructions) {
int index;
switch (instruction.OpCode.Code) {
case Code.Ldarg:
index = ((ParameterDefinition) instruction.Operand).Index;
if (index == -1 && instruction.Operand == self.ThisParameter)
index = 0;
else if (method.HasThis)
index++;
switch (index) {
case 0:
MakeMacro (instruction, OpCodes.Ldarg_0);
break;
case 1:
MakeMacro (instruction, OpCodes.Ldarg_1);
break;
case 2:
MakeMacro (instruction, OpCodes.Ldarg_2);
break;
case 3:
MakeMacro (instruction, OpCodes.Ldarg_3);
break;
default:
if (index < 256)
ExpandMacro (instruction, OpCodes.Ldarg_S, instruction.Operand);
break;
}
break;
case Code.Ldloc:
index = ((VariableDefinition) instruction.Operand).Index;
switch (index) {
case 0:
MakeMacro (instruction, OpCodes.Ldloc_0);
break;
case 1:
MakeMacro (instruction, OpCodes.Ldloc_1);
break;
case 2:
MakeMacro (instruction, OpCodes.Ldloc_2);
break;
case 3:
MakeMacro (instruction, OpCodes.Ldloc_3);
break;
default:
if (index < 256)
ExpandMacro (instruction, OpCodes.Ldloc_S, instruction.Operand);
break;
}
break;
case Code.Stloc:
index = ((VariableDefinition) instruction.Operand).Index;
switch (index) {
case 0:
MakeMacro (instruction, OpCodes.Stloc_0);
break;
case 1:
MakeMacro (instruction, OpCodes.Stloc_1);
break;
case 2:
MakeMacro (instruction, OpCodes.Stloc_2);
break;
case 3:
MakeMacro (instruction, OpCodes.Stloc_3);
break;
default:
if (index < 256)
ExpandMacro (instruction, OpCodes.Stloc_S, instruction.Operand);
break;
}
break;
case Code.Ldarga:
index = ((ParameterDefinition) instruction.Operand).Index;
if (index == -1 && instruction.Operand == self.ThisParameter)
index = 0;
else if (method.HasThis)
index++;
if (index < 256)
ExpandMacro (instruction, OpCodes.Ldarga_S, instruction.Operand);
break;
case Code.Ldloca:
if (((VariableDefinition) instruction.Operand).Index < 256)
ExpandMacro (instruction, OpCodes.Ldloca_S, instruction.Operand);
break;
case Code.Ldc_I4:
int i = (int) instruction.Operand;
switch (i) {
case -1:
MakeMacro (instruction, OpCodes.Ldc_I4_M1);
break;
case 0:
MakeMacro (instruction, OpCodes.Ldc_I4_0);
break;
case 1:
MakeMacro (instruction, OpCodes.Ldc_I4_1);
break;
case 2:
MakeMacro (instruction, OpCodes.Ldc_I4_2);
break;
case 3:
MakeMacro (instruction, OpCodes.Ldc_I4_3);
break;
case 4:
MakeMacro (instruction, OpCodes.Ldc_I4_4);
break;
case 5:
MakeMacro (instruction, OpCodes.Ldc_I4_5);
break;
case 6:
MakeMacro (instruction, OpCodes.Ldc_I4_6);
break;
case 7:
MakeMacro (instruction, OpCodes.Ldc_I4_7);
break;
case 8:
MakeMacro (instruction, OpCodes.Ldc_I4_8);
break;
default:
if (i >= -128 && i < 128)
ExpandMacro (instruction, OpCodes.Ldc_I4_S, (sbyte) i);
break;
}
break;
}
}
OptimizeBranches (self);
}
static void OptimizeBranches (MethodBody body)
{
ComputeOffsets (body);
foreach (var instruction in body.Instructions) {
if (instruction.OpCode.OperandType != OperandType.InlineBrTarget)
continue;
if (OptimizeBranch (instruction))
ComputeOffsets (body);
}
}
static bool OptimizeBranch (Instruction instruction)
{
var offset = ((Instruction) instruction.Operand).Offset - (instruction.Offset + instruction.OpCode.Size + 4);
if (!(offset >= -128 && offset <= 127))
return false;
switch (instruction.OpCode.Code) {
case Code.Br:
instruction.OpCode = OpCodes.Br_S;
break;
case Code.Brfalse:
instruction.OpCode = OpCodes.Brfalse_S;
break;
case Code.Brtrue:
instruction.OpCode = OpCodes.Brtrue_S;
break;
case Code.Beq:
instruction.OpCode = OpCodes.Beq_S;
break;
case Code.Bge:
instruction.OpCode = OpCodes.Bge_S;
break;
case Code.Bgt:
instruction.OpCode = OpCodes.Bgt_S;
break;
case Code.Ble:
instruction.OpCode = OpCodes.Ble_S;
break;
case Code.Blt:
instruction.OpCode = OpCodes.Blt_S;
break;
case Code.Bne_Un:
instruction.OpCode = OpCodes.Bne_Un_S;
break;
case Code.Bge_Un:
instruction.OpCode = OpCodes.Bge_Un_S;
break;
case Code.Bgt_Un:
instruction.OpCode = OpCodes.Bgt_Un_S;
break;
case Code.Ble_Un:
instruction.OpCode = OpCodes.Ble_Un_S;
break;
case Code.Blt_Un:
instruction.OpCode = OpCodes.Blt_Un_S;
break;
case Code.Leave:
instruction.OpCode = OpCodes.Leave_S;
break;
}
return true;
}
static void ComputeOffsets (MethodBody body)
{
var offset = 0;
foreach (var instruction in body.Instructions) {
instruction.Offset = offset;
offset += instruction.GetSize ();
}
}
}
}

33
ILSpy/NamespaceTreeNode.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.ObjectModel;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy
{
sealed class NamespaceTreeNode : SharpTreeNode
{
string name;
public string Name {
get { return name; }
}
public NamespaceTreeNode(string name)
{
if (name == null)
throw new ArgumentNullException("name");
this.name = name.Length == 0 ? "-" : name;
}
public override object Text {
get { return name; }
}
public override object Icon {
get { return Images.Namespace; }
}
}
}

97
ILSpy/TreeTraversal.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Static helper methods for traversing trees.
/// </summary>
public static class TreeTraversal
{
/// <summary>
/// Converts a tree data structure into a flat list by traversing it in pre-order.
/// </summary>
/// <param name="root">The root element of the tree.</param>
/// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in pre-order.</returns>
public static IEnumerable<T> PreOrder<T>(T root, Func<T, IEnumerable<T>> recursion)
{
return PreOrder(new T[] { root }, recursion);
}
/// <summary>
/// Converts a tree data structure into a flat list by traversing it in pre-order.
/// </summary>
/// <param name="input">The root elements of the forest.</param>
/// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in pre-order.</returns>
public static IEnumerable<T> PreOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>> recursion)
{
Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();
try {
stack.Push(input.GetEnumerator());
while (stack.Count > 0) {
while (stack.Peek().MoveNext()) {
T element = stack.Peek().Current;
yield return element;
IEnumerable<T> children = recursion(element);
if (children != null) {
stack.Push(children.GetEnumerator());
}
}
stack.Pop().Dispose();
}
} finally {
while (stack.Count > 0) {
stack.Pop().Dispose();
}
}
}
/// <summary>
/// Converts a tree data structure into a flat list by traversing it in post-order.
/// </summary>
/// <param name="root">The root element of the tree.</param>
/// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in post-order.</returns>
public static IEnumerable<T> PostOrder<T>(T root, Func<T, IEnumerable<T>> recursion)
{
return PostOrder(new T[] { root }, recursion);
}
/// <summary>
/// Converts a tree data structure into a flat list by traversing it in post-order.
/// </summary>
/// <param name="input">The root elements of the forest.</param>
/// <param name="recursion">The function that gets the children of an element.</param>
/// <returns>Iterator that enumerates the tree structure in post-order.</returns>
public static IEnumerable<T> PostOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>> recursion)
{
Stack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();
try {
stack.Push(input.GetEnumerator());
while (stack.Count > 0) {
while (stack.Peek().MoveNext()) {
T element = stack.Peek().Current;
IEnumerable<T> children = recursion(element);
if (children != null) {
stack.Push(children.GetEnumerator());
} else {
yield return element;
}
}
stack.Pop().Dispose();
if (stack.Count > 0)
yield return stack.Peek().Current;
}
} finally {
while (stack.Count > 0) {
stack.Pop().Dispose();
}
}
}
}
}

132
ILSpy/TypeTreeNode.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Media;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
sealed class TypeTreeNode : SharpTreeNode
{
readonly TypeDefinition type;
public ObservableCollection<TypeTreeNode> NestedTypes { get; private set; }
public TypeTreeNode(TypeDefinition type)
{
if (type == null)
throw new ArgumentNullException("type");
this.type = type;
this.NestedTypes = new ObservableCollection<TypeTreeNode>();
}
public string Name {
get { return type.Name; }
}
public string Namespace {
get { return type.Namespace; }
}
public override object Text {
get { return type.Name; }
}
enum ClassType
{
Class,
Enum,
Struct,
Interface,
Delegate
}
ClassType GetClassType()
{
if (type.IsValueType) {
if (type.IsEnum)
return ClassType.Enum;
else
return ClassType.Struct;
} else {
if (type.IsInterface)
return ClassType.Interface;
else if (type.BaseType != null && type.BaseType.FullName == typeof(MulticastDelegate).FullName)
return ClassType.Delegate;
else
return ClassType.Class;
}
}
public TypeAttributes Visibility {
get {
return type.Attributes & TypeAttributes.VisibilityMask;
}
}
public bool IsPublicAPI {
get {
switch (this.Visibility) {
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
case TypeAttributes.NestedFamily:
case TypeAttributes.NestedFamORAssem:
return true;
default:
return false;
}
}
}
public override object Icon {
get {
switch (this.Visibility) {
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
switch (this.GetClassType()) {
case ClassType.Delegate: return Images.Delegate;
case ClassType.Enum: return Images.Enum;
case ClassType.Interface: return Images.Interface;
case ClassType.Struct: return Images.Struct;
default: return Images.Class;
}
case TypeAttributes.NotPublic:
case TypeAttributes.NestedAssembly:
case TypeAttributes.NestedFamANDAssem:
switch (this.GetClassType()) {
case ClassType.Delegate: return Images.InternalDelegate;
case ClassType.Enum: return Images.InternalEnum;
case ClassType.Interface: return Images.InternalInterface;
case ClassType.Struct: return Images.InternalStruct;
default: return Images.InternalClass;
}
case TypeAttributes.NestedFamily:
case TypeAttributes.NestedFamORAssem:
switch (this.GetClassType()) {
case ClassType.Delegate: return Images.ProtectedDelegate;
case ClassType.Enum: return Images.ProtectedEnum;
case ClassType.Interface: return Images.ProtectedInterface;
case ClassType.Struct: return Images.ProtectedStruct;
default: return Images.ProtectedClass;
}
case TypeAttributes.NestedPrivate:
switch (this.GetClassType()) {
case ClassType.Delegate: return Images.PrivateDelegate;
case ClassType.Enum: return Images.PrivateEnum;
case ClassType.Interface: return Images.PrivateInterface;
case ClassType.Struct: return Images.PrivateStruct;
default: return Images.PrivateClass;
}
default:
throw new NotSupportedException(this.Visibility.ToString());
}
}
}
}
}
Loading…
Cancel
Save