Browse Source

Simplify the transform code by using extension methods.

pull/1/head^2
David Srbecký 18 years ago
parent
commit
9aff0b724d
  1. 12
      Decompiler.csproj
  2. 5
      lib/NRefactory/Project/NRefactory.csproj
  3. 38
      lib/NRefactory/Project/Src/Ast/INode.cs
  4. 28
      src/Transforms/Ast/RemoveGotos.cs
  5. 17
      src/Transforms/Ast/RestoreLoop.cs

12
Decompiler.csproj

@ -1,4 +1,4 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup> <PropertyGroup>
<ProjectGuid>{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}</ProjectGuid> <ProjectGuid>{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -6,6 +6,7 @@
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RootNamespace>Decompiler</RootNamespace> <RootNamespace>Decompiler</RootNamespace>
<AssemblyName>Decompiler</AssemblyName> <AssemblyName>Decompiler</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
@ -26,10 +27,19 @@
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="src" /> <Folder Include="src" />

5
lib/NRefactory/Project/NRefactory.csproj

@ -23,7 +23,7 @@
<FileAlignment>4096</FileAlignment> <FileAlignment>4096</FileAlignment>
<RunCodeAnalysis>False</RunCodeAnalysis> <RunCodeAnalysis>False</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1002;-Microsoft.Design#CA1020;-Microsoft.Design#CA1051;-Microsoft.Design#CA1062;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1305;-Microsoft.Naming#CA1704;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2227</CodeAnalysisRules> <CodeAnalysisRules>-Microsoft.Design#CA1002;-Microsoft.Design#CA1020;-Microsoft.Design#CA1051;-Microsoft.Design#CA1062;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1305;-Microsoft.Naming#CA1704;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2227</CodeAnalysisRules>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Optimize>False</Optimize> <Optimize>False</Optimize>
@ -49,6 +49,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Resources\ICSharpCode.NRefactory.snk" /> <None Include="Resources\ICSharpCode.NRefactory.snk" />

38
lib/NRefactory/Project/Src/Ast/INode.cs

@ -52,4 +52,42 @@ namespace ICSharpCode.NRefactory.Ast
/// <returns>The value the visitor returns after the visit</returns> /// <returns>The value the visitor returns after the visit</returns>
object AcceptVisitor(IAstVisitor visitor, object data); object AcceptVisitor(IAstVisitor visitor, object data);
} }
public static class INodeExtensionMethods
{
public static void Remove(this INode node)
{
node.Parent.Children.Remove(node);
}
public static INode Previous(this INode node)
{
if (node.Parent == null) return null;
int myIndex = node.Parent.Children.IndexOf(node);
int index = myIndex - 1;
if (0 <= index && index < node.Parent.Children.Count) {
return node.Parent.Children[index];
} else {
return null;
}
}
public static INode Next(this INode node)
{
if (node.Parent == null) return null;
int myIndex = node.Parent.Children.IndexOf(node);
int index = myIndex + 1;
if (0 <= index && index < node.Parent.Children.Count) {
return node.Parent.Children[index];
} else {
return null;
}
}
public static void ReplaceWith(this INode node, INode newNode)
{
int myIndex = node.Parent.Children.IndexOf(node);
node.Parent.Children[myIndex] = newNode;
}
}
} }

28
src/Transforms/Ast/RemoveGotos.cs

@ -12,19 +12,19 @@ namespace Decompiler.Transforms.Ast
base.VisitBlockStatement(blockStatement, data); base.VisitBlockStatement(blockStatement, data);
// Remove redundant jump at the end of block // Remove redundant jump at the end of block
INode lastStmt = blockStatement.Children[blockStatement.Children.Count - 1]; INode lastStmt = blockStatement.Children.Last;
// End of while loop // End of while loop
if (lastStmt is ContinueStatement && if (lastStmt is ContinueStatement &&
blockStatement.Parent is DoLoopStatement) blockStatement.Parent is DoLoopStatement)
{ {
blockStatement.Children.Remove(lastStmt); lastStmt.Remove();
return null; return null;
} }
// End of for loop // End of for loop
if (lastStmt is ContinueStatement && if (lastStmt is ContinueStatement &&
blockStatement.Parent is ForStatement) blockStatement.Parent is ForStatement)
{ {
blockStatement.Children.Remove(lastStmt); lastStmt.Remove();
return null; return null;
} }
// End of method // End of method
@ -32,21 +32,19 @@ namespace Decompiler.Transforms.Ast
blockStatement.Parent is MethodDeclaration && blockStatement.Parent is MethodDeclaration &&
((ReturnStatement)lastStmt).Expression.IsNull) ((ReturnStatement)lastStmt).Expression.IsNull)
{ {
blockStatement.Children.Remove(lastStmt); lastStmt.Remove();
return null; return null;
} }
// End of if body // End of if body
if (lastStmt is GotoStatement && if (lastStmt is GotoStatement &&
blockStatement.Parent is IfElseStatement) blockStatement.Parent is IfElseStatement)
{ {
INode ifParent = blockStatement.Parent.Parent; MyLabelStatement nextNodeAsLabel = blockStatement.Parent.Next() as MyLabelStatement;
int ifIndex = ifParent.Children.IndexOf(blockStatement.Parent);
if (ifIndex + 1 < ifParent.Children.Count) {
MyLabelStatement nextNodeAsLabel = ifParent.Children[ifIndex + 1] as MyLabelStatement;
if (nextNodeAsLabel != null) { if (nextNodeAsLabel != null) {
if (nextNodeAsLabel.NodeLabel == ((MyGotoStatement)lastStmt).NodeLabel) { if (nextNodeAsLabel.NodeLabel == ((MyGotoStatement)lastStmt).NodeLabel) {
((MyGotoStatement)lastStmt).NodeLabel.ReferenceCount--; ((MyGotoStatement)lastStmt).NodeLabel.ReferenceCount--;
blockStatement.Children.Remove(lastStmt); lastStmt.Remove();
return null;
} }
} }
} }
@ -54,22 +52,14 @@ namespace Decompiler.Transforms.Ast
return null; return null;
} }
return null;
}
public override object VisitGotoStatement(GotoStatement gotoStatement, object data) public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
{ {
MyGotoStatement myGoto = (MyGotoStatement)gotoStatement; MyGotoStatement myGoto = (MyGotoStatement)gotoStatement;
if (gotoStatement.Parent == null) return null; MyLabelStatement followingLabel = myGoto.Next() as MyLabelStatement;
int index = gotoStatement.Parent.Children.IndexOf(gotoStatement); if (followingLabel != null && followingLabel.NodeLabel == myGoto.NodeLabel) {
if (index + 1 < gotoStatement.Parent.Children.Count) {
INode nextStmt = gotoStatement.Parent.Children[index + 1];
MyLabelStatement myLabel = nextStmt as MyLabelStatement;
if (myLabel != null && myLabel.NodeLabel == myGoto.NodeLabel) {
myGoto.NodeLabel.ReferenceCount--; myGoto.NodeLabel.ReferenceCount--;
RemoveCurrentNode(); RemoveCurrentNode();
} }
}
return null; return null;
} }
} }

17
src/Transforms/Ast/RestoreLoop.cs

@ -14,15 +14,12 @@ namespace Decompiler.Transforms.Ast
// Restore loop initializer // Restore loop initializer
if (forStatement.Initializers.Count == 0) { if (forStatement.Initializers.Count == 0) {
int myIndex = forStatement.Parent.Children.IndexOf(forStatement); LocalVariableDeclaration varDeclr = forStatement.Previous() as LocalVariableDeclaration;
if (myIndex - 1 >= 0) {
LocalVariableDeclaration varDeclr = forStatement.Parent.Children[myIndex - 1] as LocalVariableDeclaration;
if (varDeclr != null) { if (varDeclr != null) {
forStatement.Parent.Children[myIndex - 1] = Statement.Null; varDeclr.ReplaceWith(Statement.Null);
forStatement.Initializers.Add(varDeclr); forStatement.Initializers.Add(varDeclr);
} }
} }
}
// Restore loop condition // Restore loop condition
if (forStatement.Condition.IsNull && if (forStatement.Condition.IsNull &&
@ -31,15 +28,13 @@ namespace Decompiler.Transforms.Ast
IfElseStatement condition = forStatement.EmbeddedStatement.Children[0] as IfElseStatement; IfElseStatement condition = forStatement.EmbeddedStatement.Children[0] as IfElseStatement;
BreakStatement breakStmt = forStatement.EmbeddedStatement.Children[1] as BreakStatement; BreakStatement breakStmt = forStatement.EmbeddedStatement.Children[1] as BreakStatement;
MyLabelStatement label = forStatement.EmbeddedStatement.Children[2] as MyLabelStatement; MyLabelStatement label = forStatement.EmbeddedStatement.Children[2] as MyLabelStatement;
if (condition != null && if (condition != null && breakStmt != null && label != null &&
breakStmt != null &&
label != null &&
condition.TrueStatement.Count == 1) condition.TrueStatement.Count == 1)
{ {
MyGotoStatement gotoStmt = condition.TrueStatement[0] as MyGotoStatement; MyGotoStatement gotoStmt = condition.TrueStatement[0] as MyGotoStatement;
if (gotoStmt != null && gotoStmt.NodeLabel == label.NodeLabel) { if (gotoStmt != null && gotoStmt.NodeLabel == label.NodeLabel) {
forStatement.EmbeddedStatement.Children.Remove(condition); condition.Remove();
forStatement.EmbeddedStatement.Children.Remove(breakStmt); breakStmt.Remove();
gotoStmt.NodeLabel.ReferenceCount--; gotoStmt.NodeLabel.ReferenceCount--;
forStatement.Condition = condition.Condition; forStatement.Condition = condition.Condition;
} }
@ -54,7 +49,7 @@ namespace Decompiler.Transforms.Ast
if (lastStmt != null) { if (lastStmt != null) {
AssignmentExpression assign = lastStmt.Expression as AssignmentExpression; AssignmentExpression assign = lastStmt.Expression as AssignmentExpression;
if (assign != null) { if (assign != null) {
forStatement.EmbeddedStatement.Children.Remove(lastStmt); lastStmt.Remove();
forStatement.Iterator.Add(lastStmt); forStatement.Iterator.Add(lastStmt);
} }
} }

Loading…
Cancel
Save