Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
c6b7ea41f1
  1. 13
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 12
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 10
      ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  4. 4
      ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs
  5. 27
      ICSharpCode.Decompiler/DecompilerException.cs
  6. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  7. 12
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  8. 14
      ILSpy/CSharpLanguage.cs
  9. 2
      ILSpy/MainWindow.xaml.cs
  10. 67
      ILSpy/TextView/DecompilerTextView.cs
  11. 10
      ILSpy/TreeNodes/TypeTreeNode.cs
  12. 16
      Mono.Cecil/Mono.Cecil/ModuleDefinition.cs
  13. 52
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs
  14. 4
      NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs
  15. 2
      SharpTreeView/TreeFlattener.cs

13
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -337,6 +337,8 @@ namespace Decompiler @@ -337,6 +337,8 @@ namespace Decompiler
Modifiers ConvertModifiers(MethodDefinition methodDef)
{
if (methodDef == null)
return Modifiers.None;
Modifiers modifiers = Modifiers.None;
if (methodDef.IsPrivate)
modifiers |= Modifiers.Private;
@ -431,7 +433,7 @@ namespace Decompiler @@ -431,7 +433,7 @@ namespace Decompiler
PropertyDeclaration CreateProperty(PropertyDefinition propDef)
{
PropertyDeclaration astProp = new PropertyDeclaration();
astProp.Modifiers = ConvertModifiers(propDef.GetMethod);
astProp.Modifiers = ConvertModifiers(propDef.GetMethod ?? propDef.SetMethod);
astProp.Name = propDef.Name;
astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
if (propDef.GetMethod != null) {
@ -469,9 +471,16 @@ namespace Decompiler @@ -469,9 +471,16 @@ namespace Decompiler
FieldDeclaration CreateField(FieldDefinition fieldDef)
{
FieldDeclaration astField = new FieldDeclaration();
astField.AddChild(new VariableInitializer(fieldDef.Name), FieldDeclaration.Roles.Variable);
VariableInitializer initializer = new VariableInitializer(fieldDef.Name);
astField.AddChild(initializer, FieldDeclaration.Roles.Variable);
astField.ReturnType = ConvertType(fieldDef.FieldType, fieldDef);
astField.Modifiers = ConvertModifiers(fieldDef);
if (fieldDef.HasConstant) {
if (fieldDef.Constant == null)
initializer.Initializer = new NullReferenceExpression();
else
initializer.Initializer = new PrimitiveExpression(fieldDef.Constant);
}
return astField;
}

12
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -21,7 +21,17 @@ namespace Decompiler @@ -21,7 +21,17 @@ namespace Decompiler
{
AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
builder.methodDef = methodDef;
return builder.CreateMethodBody();
if (Debugger.IsAttached) {
return builder.CreateMethodBody();
} else {
try {
return builder.CreateMethodBody();
} catch (OperationCanceledException) {
throw;
} catch (Exception ex) {
throw new ICSharpCode.Decompiler.DecompilerException(methodDef, ex);
}
}
}
static readonly Dictionary<string, string> typeNameToVariableNameDict = new Dictionary<string, string> {

10
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -14,6 +14,7 @@ namespace Decompiler @@ -14,6 +14,7 @@ namespace Decompiler
{
readonly ITextOutput output;
readonly Stack<AstNode> nodeStack = new Stack<AstNode>();
int braceLevelWithinType = -1;
public TextOutputFormatter(ITextOutput output)
{
@ -64,8 +65,11 @@ namespace Decompiler @@ -64,8 +65,11 @@ namespace Decompiler
public void OpenBrace(BraceStyle style)
{
if (nodeStack.OfType<BlockStatement>().Count() <= 1)
output.MarkFoldStart();
if (braceLevelWithinType >= 0 || nodeStack.Peek() is TypeDeclaration)
braceLevelWithinType++;
if (nodeStack.OfType<BlockStatement>().Count() <= 1) {
output.MarkFoldStart(defaultCollapsed: braceLevelWithinType == 1);
}
output.WriteLine();
output.WriteLine("{");
output.Indent();
@ -77,6 +81,8 @@ namespace Decompiler @@ -77,6 +81,8 @@ namespace Decompiler
output.Write('}');
if (nodeStack.OfType<BlockStatement>().Count() <= 1)
output.MarkFoldEnd();
if (braceLevelWithinType >= 0)
braceLevelWithinType--;
}
public void Indent()

4
ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs

@ -74,10 +74,12 @@ namespace Decompiler.Transforms @@ -74,10 +74,12 @@ namespace Decompiler.Transforms
}
}
// now transform the identifier into a member reference
var typeArguments = methodIdent.TypeArguments.ToArray();
methodIdent.TypeArguments = null;
MemberReferenceExpression mre = new MemberReferenceExpression {
Target = obj,
MemberName = methodIdent.Identifier,
TypeArguments = methodIdent.TypeArguments
TypeArguments = typeArguments
};
mre.AddAnnotation(method);
objectCreateExpression.Arguments = new [] { mre };

27
ICSharpCode.Decompiler/DecompilerException.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
// 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.Runtime.Serialization;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
/// <summary>
/// Desctiption of DecompilerException.
/// </summary>
public class DecompilerException : Exception, ISerializable
{
public MethodDefinition DecompiledMethod { get; set; }
public DecompilerException(MethodDefinition decompiledMethod, Exception innerException)
: base("Error decompiling " + decompiledMethod.FullName + Environment.NewLine, innerException)
{
}
// This constructor is needed for serialization.
protected DecompilerException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -64,6 +64,7 @@ @@ -64,6 +64,7 @@
<Compile Include="Ast\Transforms\RestoreLoop.cs" />
<Compile Include="Ast\Transforms\TransformationPipeline.cs" />
<Compile Include="CecilExtensions.cs" />
<Compile Include="DecompilerException.cs" />
<Compile Include="Disassembler\CodeMappings.cs" />
<Compile Include="Disassembler\DisassemblerHelpers.cs" />
<Compile Include="Disassembler\ILStructure.cs" />

12
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -106,7 +106,7 @@ namespace Decompiler @@ -106,7 +106,7 @@ namespace Decompiler
List<ByteCode> body = StackAnalysis(methodDef);
List<ILNode> ast = ConvertToAst(body, methodDef.Body.ExceptionHandlers);
List<ILNode> ast = ConvertToAst(body, new HashSet<ExceptionHandler>(methodDef.Body.ExceptionHandlers));
return ast;
}
@ -292,7 +292,7 @@ namespace Decompiler @@ -292,7 +292,7 @@ namespace Decompiler
return body;
}
List<ILNode> ConvertToAst(List<ByteCode> body, IEnumerable<ExceptionHandler> ehs)
List<ILNode> ConvertToAst(List<ByteCode> body, HashSet<ExceptionHandler> ehs)
{
List<ILNode> ast = new List<ILNode>();
@ -313,7 +313,8 @@ namespace Decompiler @@ -313,7 +313,8 @@ namespace Decompiler
// Cut the try block
{
List<ExceptionHandler> nestedEHs = ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd)).ToList();
HashSet<ExceptionHandler> nestedEHs = new HashSet<ExceptionHandler>(ehs.Where(eh => (tryStart <= eh.TryStart.Offset && eh.TryEnd.Offset < tryEnd) || (tryStart < eh.TryStart.Offset && eh.TryEnd.Offset <= tryEnd)));
ehs.ExceptWith(nestedEHs);
int tryEndIdx;
for (tryEndIdx = 0; tryEndIdx < body.Count && body[tryEndIdx].Offset != tryEnd; tryEndIdx++);
tryCatchBlock.TryBlock = new ILBlock(ConvertToAst(body.CutRange(0, tryEndIdx), nestedEHs));
@ -328,7 +329,8 @@ namespace Decompiler @@ -328,7 +329,8 @@ namespace Decompiler
// Note that the end(exclusiove) instruction may not necessarly be in our body
for (endInclusiveIndex = 0; body[endInclusiveIndex].Next.Offset != eh.HandlerEnd.Offset; endInclusiveIndex++);
int count = 1 + endInclusiveIndex - startIndex;
List<ExceptionHandler> nestedEHs = ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < eh.HandlerEnd.Offset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= eh.HandlerEnd.Offset)).ToList();
HashSet<ExceptionHandler> nestedEHs = new HashSet<ExceptionHandler>(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < eh.HandlerEnd.Offset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= eh.HandlerEnd.Offset)));
ehs.ExceptWith(nestedEHs);
List<ILNode> handlerAst = ConvertToAst(body.CutRange(startIndex, count), nestedEHs);
if (eh.HandlerType == ExceptionHandlerType.Catch) {
tryCatchBlock.CatchBlocks.Add(new ILTryCatchBlock.CatchBlock() {
@ -342,7 +344,7 @@ namespace Decompiler @@ -342,7 +344,7 @@ namespace Decompiler
}
}
ehs = ehs.Where(eh => eh.TryStart.Offset > tryEnd).ToList();
ehs.ExceptWith(handlers);
ast.Add(tryCatchBlock);
}

14
ILSpy/CSharpLanguage.cs

@ -101,6 +101,20 @@ namespace ICSharpCode.ILSpy @@ -101,6 +101,20 @@ namespace ICSharpCode.ILSpy
codeDomBuilder.GenerateCode(output, transformAbortCondition);
}
public override void DecompileAssembly(AssemblyDefinition assembly, string fileName, ITextOutput output, DecompilationOptions options)
{
if (options.FullDecompilation) {
foreach (TypeDefinition type in assembly.MainModule.Types) {
AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddType(type);
codeDomBuilder.GenerateCode(output, transformAbortCondition);
output.WriteLine();
}
} else {
base.DecompileAssembly(assembly, fileName, output, options);
}
}
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes)
{
AstType astType = AstBuilder.ConvertType(type, typeAttributes);

2
ILSpy/MainWindow.xaml.cs

@ -482,7 +482,7 @@ namespace ICSharpCode.ILSpy @@ -482,7 +482,7 @@ namespace ICSharpCode.ILSpy
}
decompilerTextView.SaveToDisk(sessionSettings.FilterSettings.Language,
treeView.GetTopLevelSelection().OfType<ILSpyTreeNode>(),
new DecompilationOptions());
new DecompilationOptions() { FullDecompilation = true });
}
#endregion

67
ILSpy/TextView/DecompilerTextView.cs

@ -240,7 +240,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -240,7 +240,7 @@ namespace ICSharpCode.ILSpy.TextView
RunWithCancellation(
delegate (CancellationToken ct) { // creation of the background task
context.Options.CancellationToken = ct;
return RunDecompiler(context, outputLengthLimit);
return DecompileAsync(context, outputLengthLimit);
},
delegate (Task<AvalonEditTextOutput> task) { // handling the result
try {
@ -269,7 +269,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -269,7 +269,7 @@ namespace ICSharpCode.ILSpy.TextView
});
}
static Task<AvalonEditTextOutput> RunDecompiler(DecompilationContext context, int outputLengthLimit)
static Task<AvalonEditTextOutput> DecompileAsync(DecompilationContext context, int outputLengthLimit)
{
Debug.WriteLine("Start decompilation of {0} tree nodes", context.TreeNodes.Length);
@ -293,10 +293,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -293,10 +293,11 @@ namespace ICSharpCode.ILSpy.TextView
} catch (AggregateException ex) {
tcs.SetException(ex);
} catch (OperationCanceledException ex) {
tcs.SetException(ex);
#else
} catch (Exception ex) {
#endif
tcs.SetException(ex);
#endif
}
}));
thread.Start();
@ -411,29 +412,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -411,29 +412,7 @@ namespace ICSharpCode.ILSpy.TextView
RunWithCancellation(
delegate (CancellationToken ct) {
context.Options.CancellationToken = ct;
return Task.Factory.StartNew(
delegate {
using (StreamWriter w = new StreamWriter(fileName)) {
try {
DecompileNodes(context, new PlainTextOutput(w));
} catch (OperationCanceledException) {
w.WriteLine();
w.WriteLine("Decompiled was cancelled.");
throw;
}
}
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.WriteLine("Decompilation complete.");
output.WriteLine();
output.AddButton(
null, "Open Explorer",
delegate {
Process.Start("explorer", "/select,\"" + fileName + "\"");
}
);
output.WriteLine();
return output;
}, TaskCreationOptions.LongRunning);
return SaveToDiskAsync(context, fileName);
},
delegate (Task<AvalonEditTextOutput> task) {
try {
@ -452,6 +431,42 @@ namespace ICSharpCode.ILSpy.TextView @@ -452,6 +431,42 @@ namespace ICSharpCode.ILSpy.TextView
}
});
}
Task<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string fileName)
{
TaskCompletionSource<AvalonEditTextOutput> tcs = new TaskCompletionSource<AvalonEditTextOutput>();
Thread thread = new Thread(new ThreadStart(
delegate {
try {
using (StreamWriter w = new StreamWriter(fileName)) {
try {
DecompileNodes(context, new PlainTextOutput(w));
} catch (OperationCanceledException) {
w.WriteLine();
w.WriteLine("Decompiled was cancelled.");
throw;
}
}
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.WriteLine("Decompilation complete.");
output.WriteLine();
output.AddButton(null, "Open Explorer", delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
output.WriteLine();
tcs.SetResult(output);
#if DEBUG
} catch (OperationCanceledException ex) {
tcs.SetException(ex);
} catch (AggregateException ex) {
tcs.SetException(ex);
#else
} catch (Exception ex) {
tcs.SetException(ex);
#endif
}
}));
thread.Start();
return tcs.Task;
}
/// <summary>
/// Cleans up a node name for use as a file name.

10
ILSpy/TreeNodes/TypeTreeNode.cs

@ -97,10 +97,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -97,10 +97,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.Children.Add(new BaseTypesTreeNode(type));
if (!type.IsSealed)
this.Children.Add(new DerivedTypesTreeNode(parentAssemblyNode.AssemblyList, type));
foreach (TypeDefinition nestedType in type.NestedTypes) {
foreach (TypeDefinition nestedType in type.NestedTypes.OrderBy(m => m.Name)) {
this.Children.Add(new TypeTreeNode(nestedType, parentAssemblyNode));
}
foreach (FieldDefinition field in type.Fields) {
foreach (FieldDefinition field in type.Fields.OrderBy(m => m.Name)) {
this.Children.Add(new FieldTreeNode(field));
}
@ -112,14 +112,14 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -112,14 +112,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
defaultMemberName = defaultMemberAttribute.ConstructorArguments[0].Value as string;
}
foreach (PropertyDefinition property in type.Properties) {
foreach (PropertyDefinition property in type.Properties.OrderBy(m => m.Name)) {
this.Children.Add(new PropertyTreeNode(property, property.Name == defaultMemberName));
}
foreach (EventDefinition ev in type.Events) {
foreach (EventDefinition ev in type.Events.OrderBy(m => m.Name)) {
this.Children.Add(new EventTreeNode(ev));
}
HashSet<MethodDefinition> accessorMethods = type.GetAccessorMethods();
foreach (MethodDefinition method in type.Methods) {
foreach (MethodDefinition method in type.Methods.OrderBy(m => m.Name)) {
if (!accessorMethods.Contains(method)) {
this.Children.Add(new MethodTreeNode(method));
}

16
Mono.Cecil/Mono.Cecil/ModuleDefinition.cs

@ -757,18 +757,22 @@ namespace Mono.Cecil { @@ -757,18 +757,22 @@ namespace Mono.Cecil {
{
return Read (this, (_, reader) => reader.LookupToken (token));
}
readonly object module_lock = new object();
internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read)
{
var position = reader.position;
var context = reader.context;
lock (module_lock) {
var position = reader.position;
var context = reader.context;
var ret = read (item, reader);
var ret = read (item, reader);
reader.position = position;
reader.context = context;
reader.position = position;
reader.context = context;
return ret;
return ret;
}
}
void ProcessDebugHeader ()

52
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs

@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp
{
@ -36,33 +37,40 @@ namespace ICSharpCode.NRefactory.CSharp @@ -36,33 +37,40 @@ namespace ICSharpCode.NRefactory.CSharp
public Modifiers Modifier {
get { return modifier; }
set {
modifier = value;
if (!lengthTable.TryGetValue (modifier, out tokenLength))
throw new InvalidOperationException ("Modifier " + modifier + " is invalid.");
for (int i = 0; i < lengthTable.Count; i++) {
if (lengthTable[i].Key == value) {
this.modifier = value;
this.tokenLength = lengthTable[i].Value;
return;
}
}
throw new ArgumentException ("Modifier " + value + " is invalid.");
}
}
static Dictionary<Modifiers, int> lengthTable = new Dictionary<Modifiers, int> () {
{ Modifiers.Public, "public".Length },
{ Modifiers.Protected, "protected".Length },
{ Modifiers.Private, "private".Length },
{ Modifiers.Internal, "internal".Length },
{ Modifiers.New, "new".Length },
{ Modifiers.Unsafe, "unsafe".Length },
{ Modifiers.Abstract, "abstract".Length },
{ Modifiers.Virtual, "virtual".Length },
{ Modifiers.Sealed, "sealed".Length },
{ Modifiers.Static, "static".Length },
{ Modifiers.Override, "override".Length },
{ Modifiers.Readonly, "readonly".Length },
{ Modifiers.Volatile, "volatile".Length },
{ Modifiers.Extern, "extern".Length },
{ Modifiers.Partial, "partial".Length },
{ Modifiers.Const, "const".Length },
// Not worth using a dictionary for such few elements.
// This table is sorted in the order that modifiers should be output when generating code.
static readonly List<KeyValuePair<Modifiers, int>> lengthTable = new List<KeyValuePair<Modifiers, int>> () {
new KeyValuePair<Modifiers, int>(Modifiers.Public, "public".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Protected, "protected".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Private, "private".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Internal, "internal".Length),
new KeyValuePair<Modifiers, int>(Modifiers.New, "new".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Unsafe, "unsafe".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Abstract, "abstract".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Virtual, "virtual".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Sealed, "sealed".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Static, "static".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Override, "override".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Readonly, "readonly".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Volatile, "volatile".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Extern, "extern".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Partial, "partial".Length),
new KeyValuePair<Modifiers, int>(Modifiers.Const, "const".Length)
};
public static ICollection<Modifiers> AllModifiers {
get { return lengthTable.Keys; }
public static IEnumerable<Modifiers> AllModifiers {
get { return lengthTable.Select(p => p.Key); }
}
public CSharpModifierToken (AstLocation location, Modifiers modifier) : base (location, 0)

4
NRefactory/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs

@ -42,7 +42,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -42,7 +42,9 @@ namespace ICSharpCode.NRefactory.CSharp
if ((m & newValue) != 0) {
if ((m & oldValue) == 0) {
// Modifier was added
node.InsertChildAfter(insertionPos, new CSharpModifierToken(AstLocation.Empty, m), ModifierRole);
var newToken = new CSharpModifierToken(AstLocation.Empty, m);
node.InsertChildAfter(insertionPos, newToken, ModifierRole);
insertionPos = newToken;
} else {
// Modifier already exists
insertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m);

2
SharpTreeView/TreeFlattener.cs

@ -81,7 +81,7 @@ namespace ICSharpCode.TreeView @@ -81,7 +81,7 @@ namespace ICSharpCode.TreeView
public int IndexOf(object item)
{
SharpTreeNode node = item as SharpTreeNode;
if (node != null && node.GetListRoot() == root) {
if (node != null && node.IsVisible && node.GetListRoot() == root) {
if (includeRoot)
return SharpTreeNode.GetVisibleIndexForNode(node);
else

Loading…
Cancel
Save