Browse Source

Add steps for transforms.

pull/728/merge
Daniel Grunwald 9 years ago
parent
commit
fe1b9dcef0
  1. 2
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  2. 22
      ICSharpCode.Decompiler/IL/Transforms/Stepper.cs
  3. 21
      ILSpy/Languages/ILAstLanguage.cs

2
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -82,7 +82,9 @@ namespace ICSharpCode.Decompiler.IL
this.CheckInvariant(ILPhase.Normal); this.CheckInvariant(ILPhase.Normal);
foreach (var transform in transforms) { foreach (var transform in transforms) {
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
context.Stepper.StartGroup(transform.GetType().Name);
transform.Run(this, context); transform.Run(this, context);
context.Stepper.EndGroup(keepIfEmpty: true);
this.CheckInvariant(ILPhase.Normal); this.CheckInvariant(ILPhase.Normal);
} }
} }

22
ICSharpCode.Decompiler/IL/Transforms/Stepper.cs

@ -18,6 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -60,7 +61,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public ILInstruction Position { get; set; } public ILInstruction Position { get; set; }
public int Step { get; set; } public int Step { get; set; }
public ICollection<Node> Children { get; } = new List<Node>(); public IList<Node> Children { get; } = new List<Node>();
} }
readonly Stack<Node> groups; readonly Stack<Node> groups;
@ -79,7 +80,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// ///
/// May throw <see cref="StepLimitReachedException"/> in debug mode. /// May throw <see cref="StepLimitReachedException"/> in debug mode.
/// </summary> /// </summary>
public void Step(string description, ILInstruction near) public void Step(string description, ILInstruction near = null)
{ {
StepInternal(description, near); StepInternal(description, near);
} }
@ -88,7 +89,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (step >= StepLimit) if (step >= StepLimit)
throw new StepLimitReachedException(); throw new StepLimitReachedException();
var stepNode = new Node { Description = $"{description} ({step})", Position = near, Step = step }; var stepNode = new Node {
Description = $"{step}: {description}",
Position = near,
Step = step
};
var p = groups.PeekOrDefault(); var p = groups.PeekOrDefault();
if (p != null) if (p != null)
p.Children.Add(stepNode); p.Children.Add(stepNode);
@ -98,14 +103,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return stepNode; return stepNode;
} }
public void StartGroup(string description, ILInstruction near) public void StartGroup(string description, ILInstruction near = null)
{ {
groups.Push(StepInternal(description, near)); groups.Push(StepInternal(description, near));
} }
public void EndGroup() public void EndGroup(bool keepIfEmpty = false)
{ {
groups.Pop(); var node = groups.Pop();
if (!keepIfEmpty && node.Children.Count == 0) {
var col = groups.PeekOrDefault()?.Children ?? steps;
Debug.Assert(col.Last() == node);
col.RemoveAt(col.Count - 1);
}
} }
} }
} }

21
ILSpy/Languages/ILAstLanguage.cs

@ -99,22 +99,9 @@ namespace ICSharpCode.ILSpy
{ {
yield return new TypedIL(); yield return new TypedIL();
CSharpDecompiler decompiler = new CSharpDecompiler(ModuleDefinition.CreateModule("Dummy", ModuleKind.Dll), new DecompilerSettings()); CSharpDecompiler decompiler = new CSharpDecompiler(ModuleDefinition.CreateModule("Dummy", ModuleKind.Dll), new DecompilerSettings());
for (int i = 0; i <= decompiler.ILTransforms.Count; i++) { yield return new BlockIL(decompiler.ILTransforms.ToList());
yield return MakeDebugLanguage(decompiler.ILTransforms.Take(i));
var loop = decompiler.ILTransforms.ElementAtOrDefault(i) as LoopingTransform;
if (loop != null) {
for (int j = 1; j <= loop.Transforms.Count; j++) {
yield return MakeDebugLanguage(decompiler.ILTransforms.Take(i).Concat(loop.Transforms.Take(j)));
}
}
}
} }
static ILAstLanguage MakeDebugLanguage(IEnumerable<IILTransform> transforms)
{
return new BlockIL(transforms.ToList());
}
public override string FileExtension { public override string FileExtension {
get { get {
return ".il"; return ".il";
@ -155,7 +142,7 @@ namespace ICSharpCode.ILSpy
{ {
readonly IReadOnlyList<IILTransform> transforms; readonly IReadOnlyList<IILTransform> transforms;
public BlockIL(IReadOnlyList<IILTransform> transforms) : base(transforms.Count == 0 ? "ILAst (blocks)" : "ILAst (" + transforms.Last().GetType().Name + ")") public BlockIL(IReadOnlyList<IILTransform> transforms) : base("ILAst")
{ {
this.transforms = transforms; this.transforms = transforms;
} }
@ -170,6 +157,8 @@ namespace ICSharpCode.ILSpy
ILFunction il = reader.ReadIL(method.Body, options.CancellationToken); ILFunction il = reader.ReadIL(method.Body, options.CancellationToken);
ILTransformContext context = new ILTransformContext { Settings = options.DecompilerSettings, TypeSystem = typeSystem }; ILTransformContext context = new ILTransformContext { Settings = options.DecompilerSettings, TypeSystem = typeSystem };
context.Stepper.StepLimit = options.StepLimit; context.Stepper.StepLimit = options.StepLimit;
// Because the UI only allows viewing the result of a step, add a dummy initial step.
context.Stepper.Step("Initial");
try { try {
il.RunTransforms(transforms, context); il.RunTransforms(transforms, context);
} catch (StepLimitReachedException) { } catch (StepLimitReachedException) {

Loading…
Cancel
Save