Author: mkrueger
Date: 2008-02-16 08:57:04 -0500 (Sat, 16 Feb 2008)
New Revision: 95870

Added:
   
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/Decompiler.cs
Modified:
   trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/ChangeLog
   trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/Makefile.am
   
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser.mdp
   
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/DomMethodNodeBuilder.cs
Log:
* MonoDevelop.AssemblyBrowser/Decompiler.cs,
  MonoDevelop.AssemblyBrowser/DomMethodNodeBuilder.cs: Added basic c#
  decompiler (Very BASIC).

Modified: 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/ChangeLog
===================================================================
--- trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/ChangeLog     
2008-02-16 13:55:41 UTC (rev 95869)
+++ trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/ChangeLog     
2008-02-16 13:57:04 UTC (rev 95870)
@@ -1,3 +1,9 @@
+2008-02-16  Mike Krüger <[EMAIL PROTECTED]> 
+
+       * MonoDevelop.AssemblyBrowser/Decompiler.cs,
+         MonoDevelop.AssemblyBrowser/DomMethodNodeBuilder.cs: Added basic c#
+         decompiler (Very BASIC).
+
 2008-02-15  Mike Krüger <[EMAIL PROTECTED]> 
 
        * MonoDevelop.AssemblyBrowser.Dom/DomCecilType.cs: Changed dom.

Modified: 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/Makefile.am
===================================================================
--- trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/Makefile.am   
2008-02-16 13:55:41 UTC (rev 95869)
+++ trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/Makefile.am   
2008-02-16 13:57:04 UTC (rev 95870)
@@ -18,6 +18,7 @@
        MonoDevelop.AssemblyBrowser/AssemblyNodeBuilder.cs \
        MonoDevelop.AssemblyBrowser/BaseTypeFolder.cs \
        MonoDevelop.AssemblyBrowser/BaseTypeFolderNodeBuilder.cs \
+       MonoDevelop.AssemblyBrowser/Decompiler.cs \
        MonoDevelop.AssemblyBrowser/DisplayBinding.cs \
        MonoDevelop.AssemblyBrowser/DomEventNodeBuilder.cs \
        MonoDevelop.AssemblyBrowser/DomFieldNodeBuilder.cs \

Added: 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/Decompiler.cs
===================================================================
--- 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/Decompiler.cs
     2008-02-16 13:55:41 UTC (rev 95869)
+++ 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/Decompiler.cs
     2008-02-16 13:57:04 UTC (rev 95870)
@@ -0,0 +1,660 @@
+//
+// Decompiler.cs
+//
+// Author:
+//   Andrea Paatz <[EMAIL PROTECTED]>
+//   Mike Krüger <[EMAIL PROTECTED]>
+//
+// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
+//
+// 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 System.Text;
+using System.Collections.Generic;
+
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+using MonoDevelop.AssemblyBrowser.Dom;
+
+namespace MonoDevelop.AssemblyBrowser
+{
+       public class Decompiler
+       {
+               enum OperationType 
+               {
+                       Primary        = 1,
+                       Unary          = 2,
+                       Multiplicative = 3,
+                       Additive       = 4,
+                       Shift          = 6,
+                       Relational     = 7,
+                       Equality       = 8,
+                       LogicalAnd     = 9,
+                       LogicalXor     = 10,
+                       LogicalOr      = 11,
+                       ConditionalAnd = 12,
+                       ConditionalOr  = 13,
+                       Conditional    = 14,
+                       Assignment     = 15
+               }
+               
+               class Operand
+               {
+                       string stringValue;
+                       OperationType operationType;
+                       
+                       public string StringValue {
+                               get { return stringValue; }
+                       }
+                       
+                       public OperationType OperationType {
+                               get { return operationType; }
+                       }
+                       
+                       public Operand (string stringValue) : this 
(stringValue, OperationType.Primary)
+                       {
+                       }
+                       
+                       public Operand (string stringValue, OperationType 
operationType) 
+                       {
+                               this.stringValue   = stringValue;
+                               this.operationType = operationType;
+                       }
+               } // class Operand
+               
+               class Statement 
+               {
+                       static int labelcount = 1;
+                       int line = -1;
+                       string s;
+                       string label = "";
+                       
+                       public int Line {
+                               get {
+                                       return line;
+                               }
+                               set {
+                                       if (line < 0)
+                                               line = value;
+                               }
+                       }
+                       
+                       public bool HasLabel() 
+                       {
+                               return label != "";
+                       }
+                       
+                       public string Label {
+                               get {
+                                       return label;
+                               }
+                               set {
+                                       label = value;
+                               }
+                       }
+                       
+                       public string StringValue {
+                               get {
+                                       return s;
+                               }
+                               set {
+                                       s = value;
+                               }
+                       }
+                       
+                       public static string Nextlabel () 
+                       {
+                               return ("l" + labelcount++);
+                       }
+                       
+                       public Statement (int line, string text)
+                       {
+                               this.line = line;
+                               this.s = text;
+                       }
+                       
+                       public Statement ()
+                       {
+                       }
+               } // Statement
+               
+               string GetOperatorChar (Code c)
+               {
+                       switch (c) {
+                       case Code.Add:
+                               return "+";
+                       case Code.Mul:
+                               return "*";
+                       case Code.Sub:
+                               return "-";
+                       case Code.Div:
+                               return "/";
+                       case Code.Rem:
+                               return "%";
+                       case Code.And:
+                               return "&";
+                       case Code.Or:
+                               return "|";
+                       case Code.Xor:
+                               return "^";
+                       case Code.Shl:
+                               return "<<";
+                       case Code.Shr:
+                               return ">>";
+                       case Code.Beq:
+                       case Code.Ceq:
+                               return "==";
+                       case Code.Bgt:
+                       case Code.Cgt:
+                               return ">";
+                       case Code.Bge:
+                               return ">=";
+                       case Code.Blt:
+                       case Code.Clt:
+                               return "<";
+                       case Code.Ble:
+                               return "<=";
+                       default:
+                               return "error " + c;
+                       }
+               }
+               
+               OperationType GetOperatorPrecedence (Code c)
+               {
+                       switch (c) {
+                       case Code.Add:
+                       case Code.Sub:
+                               return OperationType.Additive;
+                       case Code.Mul:
+                       case Code.Div:
+                       case Code.Rem:
+                               return OperationType.Multiplicative;
+                       case Code.And:
+                               return OperationType.LogicalAnd;
+                       case Code.Or:
+                               return OperationType.LogicalOr;
+                       case Code.Xor:
+                               return OperationType.LogicalXor;
+                       case Code.Shl:
+                       case Code.Shr:
+                               return OperationType.Shift;
+                       case Code.Beq:
+                       case Code.Bgt:
+                       case Code.Blt:
+                       case Code.Bge:
+                       case Code.Ble:
+                       case Code.Ceq:
+                       case Code.Cgt:
+                       case Code.Clt:
+                               return OperationType.Relational;
+                       default:
+                               return OperationType.Assignment;
+                       }
+               }
+               
+               int GetLoadArgumentNumber (Code c, bool isStatic)
+               {
+                       int result = 0;
+                       switch (c) {
+                       case Code.Ldarg_0:
+                               result = 0;
+                               break;
+                       case Code.Ldarg_1:
+                               result = 1;
+                               break;
+                       case Code.Ldarg_2:
+                               result = 2;
+                               break;
+                       case Code.Ldarg_3:
+                               result = 3;
+                               break;
+                       }
+                       if (!isStatic) {
+                               result--;
+                       }
+                       return result;
+               }
+               
+               string GetVariableName (Code c)
+               {
+                       switch (c) {
+                       case Code.Ldloc_0:
+                       case Code.Stloc_0:
+                               return "loc0";
+                       case Code.Ldloc_1:
+                       case Code.Stloc_1:
+                               return "loc1";
+                       case Code.Ldloc_2:
+                       case Code.Stloc_2:
+                               return "loc2";
+                       case Code.Ldloc_3:
+                       case Code.Stloc_3:
+                               return "loc3";
+                       }
+                       return "error" + c;
+               }
+               
+               string GetConst (Code c)
+               {
+                       switch (c) {
+                       case Code.Ldc_I4_M1:
+                               return "-1";
+                       case Code.Ldc_I4_0:
+                               return "0";
+                       case Code.Ldc_I4_1:
+                               return "1";
+                       case Code.Ldc_I4_2:
+                               return "2";
+                       case Code.Ldc_I4_3:
+                               return "3";
+                       case Code.Ldc_I4_4:
+                               return "4";
+                       case Code.Ldc_I4_5:
+                               return "5";
+                       case Code.Ldc_I4_6:
+                               return "6";
+                       case Code.Ldc_I4_7:
+                               return "7";
+                       case Code.Ldc_I4_8:
+                               return "8";
+                       case Code.Ldnull:
+                               return "null";
+                       }
+                       return "error" + c;
+               }
+               
+               Dictionary<int, Statement> statements = new Dictionary<int, 
Statement>();
+               
+               void SetStatement (Statement statement)
+               {
+                       if (!statements.ContainsKey (statement.Line)) {
+                               statements.Add (statement.Line, statement);
+                       } else {
+                               statements[statement.Line].StringValue = 
statement.StringValue;
+                       }
+               }
+               
+               public string Decompile(MonoDevelop.Ide.Gui.Pads.ITreeNavigator 
navigator)
+               {
+                       Statement current = new Statement();
+                       StringBuilder result = new StringBuilder ();
+                       Stack<Operand> stack = new Stack<Operand>();
+                       DomCecilMethod method = navigator.DataItem as 
DomCecilMethod;
+                       foreach (Instruction instruction in 
method.MethodDefinition.Body.Instructions) {
+                               string arg1, arg2, name;
+                               bool fullname = false;
+                               int i;
+                               try {
+                                       MethodReference calledMethod;
+                                       switch (instruction.OpCode.Code) {
+                                       case Code.Box:
+                                               break;
+                                       case Code.Add:
+                                       case Code.Sub:
+                                       case Code.Div:
+                                       case Code.Mul:
+                                       case Code.Rem:
+                                       case Code.And:
+                                       case Code.Or:
+                                       case Code.Xor:
+                                       case Code.Shl:
+                                       case Code.Shr:
+                                       case Code.Ceq:
+                                       case Code.Cgt:
+                                       case Code.Clt:
+                                               OperationType precedence = 
GetOperatorPrecedence (instruction.OpCode.Code);
+                                               if (stack.Peek().OperationType 
> precedence)
+                                                       arg2 = "(" + 
stack.Pop().StringValue + ")";
+                                               else
+                                                       arg2 = 
stack.Pop().StringValue;
+                                               if (stack.Peek().OperationType 
> precedence)
+                                                       arg1 = "(" + 
stack.Pop().StringValue + ")";
+                                               else
+                                                       arg1 = 
stack.Pop().StringValue;
+                                               stack.Push(new Operand(arg1 + ' 
' + GetOperatorChar(instruction.OpCode.Code) + ' ' + arg2, precedence));
+                                               break;
+                                       case Code.Castclass:
+                                               if (stack.Peek().OperationType 
> OperationType.Assignment)
+                                                       arg1 = "(" + 
stack.Pop().StringValue + ")";
+                                               else
+                                                       arg1 = 
stack.Pop().StringValue;
+                                               stack.Push(new Operand("(" +  
instruction.Operand.ToString() + ")" + arg1, OperationType.Assignment));
+                                               break;
+                                       case Code.Ldarg_0:
+                                       case Code.Ldarg_1:
+                                       case Code.Ldarg_2:
+                                       case Code.Ldarg_3:
+                                               current.Line = 
instruction.Offset;
+                                               i = 
GetLoadArgumentNumber(instruction.OpCode.Code, method.IsStatic);
+                                               if (i >= 0)
+                                                       stack.Push(new 
Operand(method.MethodDefinition.Parameters[i].Name.ToString()));
+                                               break;
+                                       case Code.Ldarg_S:
+                                               current.Line = 
instruction.Offset;
+                                               name = 
instruction.Operand.ToString();
+                                               stack.Push(new Operand(name));
+                                               break;
+                                       case Code.Starg_S:
+                                               name = 
instruction.Operand.ToString();
+                                               current.StringValue = (name + " 
= " + stack.Pop().StringValue + ";");
+                                               SetStatement (current);
+                                               current = new Statement();
+                                               break;
+                                       case Code.Stloc_0:
+                                       case Code.Stloc_1:
+                                       case Code.Stloc_2:
+                                       case Code.Stloc_3:
+                                               current.StringValue = 
(GetVariableName (instruction.OpCode.Code) + " = " + stack.Pop().StringValue + 
";");
+                                               SetStatement (current);
+                                               current = new Statement();
+                                               break;
+                                       case Code.Stloc_S:
+                                               name = 
instruction.Operand.ToString();
+                                               current.StringValue = (name + " 
= " + stack.Pop().StringValue + ";");
+                                               SetStatement (current);
+                                               current = new Statement();
+                                               break;
+                                       case Code.Stfld:
+                                       case Code.Stsfld:
+                                               FieldReference field = 
(FieldReference)instruction.Operand;
+                                               current.StringValue = 
field.Name + " = " + stack.Pop().StringValue + ";";
+                                               SetStatement (current);
+                                               current = new Statement();
+                                               break;
+                                       case Code.Stelem_I:
+                                       case Code.Stelem_I1:
+                                       case Code.Stelem_I2:
+                                       case Code.Stelem_I4:
+                                       case Code.Stelem_I8:
+                                       case Code.Stelem_R4:
+                                       case Code.Stelem_R8:
+                                       case Code.Stelem_Ref:
+                                               arg2 = stack.Pop().StringValue;
+                                               arg1 = stack.Pop().StringValue;
+                                               current.StringValue = stack.Pop 
().StringValue + "[" + arg1 + "] = " + arg2;
+                                               SetStatement (current);
+                                               current = new Statement ();
+                                               break;
+                                       case Code.Ldelem_I: // hope the only 
difference between them is the Type of the Array Elements
+                                       case Code.Ldelem_I1:
+                                       case Code.Ldelem_I2:
+                                       case Code.Ldelem_I4:
+                                       case Code.Ldelem_I8:
+                                       case Code.Ldelem_R4:
+                                       case Code.Ldelem_R8:
+                                       case Code.Ldelem_Ref:
+                                               arg1 = stack.Pop ().StringValue;
+                                               stack.Push (new Operand 
(stack.Pop ().StringValue + "[" + arg1 + "]"));
+                                               break;
+                                       case Code.Ldloc_0:
+                                       case Code.Ldloc_1:
+                                       case Code.Ldloc_2:
+                                       case Code.Ldloc_3:
+                                               current.Line = 
instruction.Offset;
+                                               stack.Push (new Operand 
(GetVariableName (instruction.OpCode.Code)));
+                                               break;
+                                       case Code.Ldloc_S:
+                                               current.Line = 
instruction.Offset;
+                                               name = 
instruction.Operand.ToString ();
+                                               stack.Push (new Operand (name));
+                                               break;
+                                       case Code.Ldstr:
+                                               current.Line = 
instruction.Offset;
+                                               name = 
instruction.Operand.ToString ();
+                                               stack.Push (new Operand ('"' + 
name + '"'));
+                                               break;
+                                       case Code.Ldc_I4_M1:
+                                       case Code.Ldc_I4_0:
+                                       case Code.Ldc_I4_1:
+                                       case Code.Ldc_I4_2:
+                                       case Code.Ldc_I4_3:
+                                       case Code.Ldc_I4_4:
+                                       case Code.Ldc_I4_5:
+                                       case Code.Ldc_I4_6:
+                                       case Code.Ldc_I4_7:
+                                       case Code.Ldc_I4_8:
+                                       case Code.Ldnull:
+                                               current.Line = 
instruction.Offset;
+                                               stack.Push (new Operand 
(GetConst (instruction.OpCode.Code)));
+                                               break;
+                                       case Code.Ldc_I4_S:
+                                               current.Line = 
instruction.Offset;
+                                               name = 
instruction.Operand.ToString ();
+                                               stack.Push (new Operand (name));
+                                               break;
+                                       case Code.Ldc_I4:
+                                               current.Line = 
instruction.Offset;
+                                               name = 
instruction.Operand.ToString ();
+                                               stack.Push (new Operand (name));
+                                               break;
+                                       case Code.Ldftn:
+                                               current.Line = 
instruction.Offset;
+                                               calledMethod = 
(MethodReference)instruction.Operand;
+                                               name = calledMethod.ToString ();
+                                               stack.Push (new Operand (name));
+                                               break;
+                                       case Code.Ldfld:
+                                       case Code.Ldsfld:
+                                               field = 
(FieldReference)instruction.Operand;
+                                               current.Line = 
instruction.Offset;
+                                               stack.Push (new Operand 
(field.Name));
+                                               break;
+                                       case Code.Call:
+                                               current.Line = 
instruction.Offset;
+                                               calledMethod = 
(MethodReference)instruction.Operand;
+                                               name = calledMethod.ToString ();
+                                               fullname = 
(method.MethodDefinition.DeclaringType != calledMethod.DeclaringType);
+                                               if (CallType (name) == 
"System.Void") {
+                                                       current.StringValue = 
MethodCall (stack, instruction, fullname) + ";";
+                                                       SetStatement (current);
+                                                       current = new Statement 
();
+                                               } else {
+                                                       current.Line = 
instruction.Offset;
+                                                       stack.Push (new Operand 
(MethodCall (stack, instruction, fullname)));
+                                               }
+                                               break;
+                                       case Code.Callvirt:
+                                               calledMethod = 
(MethodReference)instruction.Operand;
+                                               name = calledMethod.ToString ();
+                                               if (CallType (name) == 
"System.Void") {
+                                                       current.StringValue = 
MethodCall (stack, instruction, false) + ";";
+                                                       arg1 = stack.Pop 
().StringValue; // TODO: check for precedences
+                                                       current.StringValue = 
arg1 + '.' + current.StringValue;
+                                                       SetStatement (current);
+                                                       current = new Statement 
();
+                                               } else {
+                                                       current.Line = 
instruction.Offset;
+                                                       string s = MethodCall 
(stack, instruction, fullname);
+                                                       arg1 = stack.Pop 
().StringValue; // TODO: check for precedences
+                                                       stack.Push (new Operand 
(arg1 + '.' + s));
+                                               }
+                                               break;
+                                       case Code.Pop:
+                                               current.StringValue = stack.Pop 
().StringValue + ";";
+                                               SetStatement (current);
+                                               current = new Statement ();
+                                               break;
+                                       case Code.Newarr:
+                                               current.Line = 
instruction.Offset;
+                                               name = 
instruction.Operand.ToString ();
+                                               StringBuilder str = new 
StringBuilder ();
+                                               str.Append ("new ");
+                                               str.Append (name);
+                                               str.Append ("[");
+                                               str.Append (stack.Pop 
().StringValue);
+                                               str.Append ("]");
+                                               stack.Push (new Operand 
(str.ToString()));
+                                               break;
+                                       case Code.Newobj:
+                                               current.Line = 
instruction.Offset;
+                                               calledMethod = 
(MethodReference)instruction.Operand;
+                                               fullname = 
(method.MethodDefinition.DeclaringType != calledMethod.DeclaringType);
+                                               str = new StringBuilder ();
+                                               if (fullname) {
+                                                       str.Append 
(calledMethod.DeclaringType.FullName);
+                                               } else {
+                                                       str.Append 
(calledMethod.DeclaringType.Name);
+                                               }
+                                               str.Append('(');
+                                               if 
(calledMethod.Parameters.Count > 0) {
+                                                       Operand[] op = new 
Operand[calledMethod.Parameters.Count];
+                                                       for (i = 
calledMethod.Parameters.Count - 1; i >= 0; --i) {
+                                                               op [i] = 
stack.Pop ();
+                                                       }
+                                                       str.Append 
(op[0].StringValue);
+                                                       for (i = 1; i < 
calledMethod.Parameters.Count; ++i) {
+                                                               str.Append (", 
");
+                                                               str.Append 
(op[i].StringValue);
+                                                       }
+                                               }
+                                               str.Append (")");
+                                               stack.Push (new Operand ("new " 
+ str));
+                                               break;
+                                       case Code.Throw:
+                                               current.StringValue = "throw "+ 
stack.Pop ().StringValue + ";";
+                                               SetStatement (current);
+                                               current = new Statement ();
+                                               break;
+                                       case Code.Beq:
+                                       case Code.Bgt:
+                                       case Code.Bge:
+                                       case Code.Blt:
+                                       case Code.Ble:
+                                               precedence = 
GetOperatorPrecedence (instruction.OpCode.Code);
+                                               if (stack.Peek ().OperationType 
> precedence)
+                                                       arg2 = "(" + stack.Pop 
().StringValue + ")";
+                                               else
+                                                       arg2 = 
stack.Pop().StringValue;
+                                               if (stack.Peek ().OperationType 
> precedence)
+                                                       arg1 = "(" + stack.Pop 
().StringValue + ")";
+                                               else
+                                                       arg1 = 
stack.Pop().StringValue;
+                                               stack.Push (new Operand (arg1 + 
' ' + GetOperatorChar (instruction.OpCode.Code) + ' ' + arg2, precedence));
+                                               goto case Code.Br;
+                                       case Code.Br:
+                                       case Code.Brfalse:
+                                       case Code.Brtrue:
+                                               if (instruction.OpCode.Code == 
Code.Br)
+                                                       current.Line = 
instruction.Offset;
+                                               Mono.Cecil.Cil.Instruction 
instr = (Mono.Cecil.Cil.Instruction)instruction.Operand;
+                                               int target = instr.Offset;
+                                               string label = 
Statement.Nextlabel ();
+                                               if (statements.ContainsKey 
(target)) {
+                                                       
if(statements[target].HasLabel ())
+                                                               label = 
statements[target].Label;
+                                                       else
+                                                               
statements[target].Label = label;
+                                               } else {
+                                                       Statement s = new 
Statement ();
+                                                       s.Label = label;
+                                                       statements.Add (target, 
s);
+                                               }
+                                               name  = "goto " + label + ";";
+                                               if (instruction.OpCode.Code != 
Code.Br) {
+                                                       string not = 
(instruction.OpCode.Code == Code.Brfalse) ? "!" : "";
+                                                       name = "if (" + not + 
stack.Pop ().StringValue + ") " + name;
+                                               }
+                                               current.StringValue = name;
+                                               SetStatement (current);
+                                               current = new Statement ();
+                                               break;
+                                       case Code.Ret:
+                                               Console.WriteLine 
(method.ReturnType.Name);
+                                               if (method.ReturnType.Name != 
"Void") {
+                                                       current.StringValue = 
("return " + stack.Pop ().StringValue + ";");
+                                                       SetStatement (current);
+                                                       current = new Statement 
();
+                                               } else {
+                                                       current.Line = 
instruction.Offset;
+                                                       current.StringValue = 
("return;");
+                                                       SetStatement (current);
+                                                       current = new Statement 
();
+                                               }
+                                               break;
+                                       default:
+                                               current.Line = 
instruction.Offset;
+                                               if (!statements.ContainsKey 
(instruction.Offset))
+                                                       statements.Add 
(instruction.Offset, new Statement (instruction.Offset, "\n  unknown opcode: " 
+ instruction.OpCode.Code + '\n'));
+                                               else
+                                                       
statements[instruction.Offset].StringValue += "\n  unknown opcode: " + 
instruction.OpCode.Code + '\n';
+                                               break;
+                                       }
+                               } catch (Exception e) {
+                                       result.Append ("exception:" + e);
+                               }
+                               result.Length = 0;
+                               result.AppendLine ();
+                               int[] sortedKeys = new int [statements.Count];
+                               statements.Keys.CopyTo (sortedKeys, 0);
+                               Array.Sort (sortedKeys);
+                               foreach (int k in sortedKeys) {
+                                       result.Append (String.Format("{0:X4}", 
k) + ":  ");
+                                       if (statements[k].HasLabel ()) {
+                                               result.Append 
(statements[k].Label + ": ");
+                                       } else {
+                                               result.Append ("     ");
+                                       }
+                                       result.Append 
(statements[k].StringValue);
+                                       result.AppendLine ();
+                               }
+                       }
+                       result.AppendLine ();
+                       return result.ToString ();
+               }
+               
+               string CallType (string call)
+               {
+                       int end = call.IndexOf (" ");
+                       return call.Substring (0, end);
+               }
+               
+               string MethodCall (Stack<Operand> stack, Instruction 
instruction, bool fullname)
+               {
+                       MethodReference calledMethod = 
(MethodReference)instruction.Operand;
+                       StringBuilder result = new StringBuilder ();
+                       if (fullname) {
+                               result.Append 
(calledMethod.DeclaringType.FullName);
+                               result.Append ('.');
+                       }
+                       result.Append (calledMethod.Name);
+                       result.Append ('(');
+                       if (calledMethod.Parameters.Count > 0) {
+                               Operand[] op = new 
Operand[calledMethod.Parameters.Count];
+                               for (int i = calledMethod.Parameters.Count - 1; 
i >= 0; --i) {
+                                       op [i] = stack.Pop ();
+                               }
+                               result.Append (op[0].StringValue);
+                               for (int i = 1; i < 
calledMethod.Parameters.Count; ++i) {
+                                       result.Append (", ");
+                                       result.Append (op[i].StringValue);
+                               }
+                       }
+                       result.Append (")");
+                       return result.ToString ();
+               }
+               
+               public Decompiler ()
+               {
+               }
+       }
+}
\ No newline at end of file

Modified: 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/DomMethodNodeBuilder.cs
===================================================================
--- 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/DomMethodNodeBuilder.cs
   2008-02-16 13:55:41 UTC (rev 95869)
+++ 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/DomMethodNodeBuilder.cs
   2008-02-16 13:57:04 UTC (rev 95870)
@@ -103,6 +103,7 @@
                        return String.Format ("IL_{0:X4}", instruction.Offset);
                }
                
+               
                string IAssemblyBrowserNodeBuilder.GetDisassembly 
(ITreeNavigator navigator)
                {
                        DomCecilMethod method = navigator.DataItem as 
DomCecilMethod;
@@ -116,6 +117,7 @@
                        }
                        
                        StringBuilder result = new StringBuilder ();
+                       
                        foreach (Instruction instruction in 
method.MethodDefinition.Body.Instructions ) {
                                result.Append ("<b>");
                                result.Append (GetInstructionOffset 
(instruction));
@@ -137,10 +139,18 @@
                                result.Append ("</i>");
                                result.AppendLine ();
                        }
-                                       
+                       result.AppendLine ();
+                       
+                       try {
+                               string decompiledCode = new 
Decompiler().Decompile (navigator);
+                               result.Append (Ambience.Format 
(decompiledCode));
+                       } catch (Exception e) {
+                               result.Append ("got exception while 
decompilation: \n" + e);
+                       }
+                       
                        return result.ToString ();
                }
                #endregion
 
        }
-}
+}
\ No newline at end of file

Modified: 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser.mdp
===================================================================
--- 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser.mdp
       2008-02-16 13:55:41 UTC (rev 95869)
+++ 
trunk/monodevelop/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser.mdp
       2008-02-16 13:57:04 UTC (rev 95870)
@@ -53,6 +53,7 @@
     <File name="MonoDevelop.AssemblyBrowser.Dom/DomCecilAttribute.cs" 
subtype="Code" buildaction="Compile" />
     <File name="gtk-gui/generated.cs" subtype="Code" buildaction="Compile" />
     <File name="gtk-gui/MonoDevelop.AssemblyBrowser.AssemblyBrowserWidget.cs" 
subtype="Code" buildaction="Compile" />
+    <File name="MonoDevelop.AssemblyBrowser/Decompiler.cs" subtype="Code" 
buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, 
Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to