mirror of https://github.com/icsharpcode/ILSpy.git
Browse Source
Added an Ast transform to remove dead labels. (first Ast transform in program, I expect many more to come. Some stuff should be rewritten to use these explicit transforms)pull/1/head^2
6 changed files with 119 additions and 28 deletions
@ -0,0 +1,40 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
using Ast = ICSharpCode.NRefactory.Ast; |
||||||
|
using Decompiler.ControlFlow; |
||||||
|
|
||||||
|
namespace ICSharpCode.NRefactory.Ast |
||||||
|
{ |
||||||
|
public class MyGotoStatement: Ast.GotoStatement |
||||||
|
{ |
||||||
|
NodeLabel nodeLabel; |
||||||
|
|
||||||
|
public NodeLabel NodeLabel { |
||||||
|
get { return nodeLabel; } |
||||||
|
} |
||||||
|
|
||||||
|
public MyGotoStatement(NodeLabel nodeLabel): base(nodeLabel.Label) |
||||||
|
{ |
||||||
|
this.nodeLabel = nodeLabel; |
||||||
|
|
||||||
|
this.nodeLabel.ReferenceCount++; |
||||||
|
} |
||||||
|
|
||||||
|
public static Ast.Statement Create(Node contextNode, Node targetNode) |
||||||
|
{ |
||||||
|
// Propagate target up to the top most scope
|
||||||
|
while (targetNode.Parent != null && targetNode.Parent.HeadChild == targetNode) { |
||||||
|
targetNode = targetNode.Parent; |
||||||
|
} |
||||||
|
// If branches to the start of encapsulating loop
|
||||||
|
if (contextNode.Parent is Loop && targetNode == contextNode.Parent) { |
||||||
|
return new Ast.ContinueStatement(); |
||||||
|
} |
||||||
|
// If branches outside the encapsulating loop
|
||||||
|
if (contextNode.Parent is Loop && targetNode == contextNode.Parent.NextNode) { |
||||||
|
return new Ast.BreakStatement(); |
||||||
|
} |
||||||
|
return new Ast.MyGotoStatement(targetNode.Label); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
using Ast = ICSharpCode.NRefactory.Ast; |
||||||
|
using Decompiler.ControlFlow; |
||||||
|
|
||||||
|
namespace ICSharpCode.NRefactory.Ast |
||||||
|
{ |
||||||
|
public class MyLabelStatement: Ast.LabelStatement |
||||||
|
{ |
||||||
|
NodeLabel nodeLabel; |
||||||
|
|
||||||
|
public NodeLabel NodeLabel { |
||||||
|
get { return nodeLabel; } |
||||||
|
} |
||||||
|
|
||||||
|
public MyLabelStatement(NodeLabel nodeLabel): base(nodeLabel.Label) |
||||||
|
{ |
||||||
|
this.nodeLabel = nodeLabel; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
using ICSharpCode.NRefactory.Ast; |
||||||
|
using ICSharpCode.NRefactory.Visitors; |
||||||
|
|
||||||
|
namespace Decompiler.Transforms.Ast |
||||||
|
{ |
||||||
|
public class RemoveDeadLabels: AbstractAstTransformer |
||||||
|
{ |
||||||
|
public override object VisitLabelStatement(LabelStatement labelStatement, object data) |
||||||
|
{ |
||||||
|
MyLabelStatement myLabel = (MyLabelStatement)labelStatement; |
||||||
|
if (myLabel.NodeLabel.ReferenceCount == 0) { |
||||||
|
RemoveCurrentNode(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue