diff --git a/ICSharpCode.Decompiler/CSharp/Annotations.cs b/ICSharpCode.Decompiler/CSharp/Annotations.cs
index 928c9ab12..32ca01b82 100644
--- a/ICSharpCode.Decompiler/CSharp/Annotations.cs
+++ b/ICSharpCode.Decompiler/CSharp/Annotations.cs
@@ -11,6 +11,7 @@ using System.Collections;
using System.Collections.Generic;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Semantics;
+using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.Decompiler.IL;
namespace ICSharpCode.Decompiler.CSharp
@@ -72,5 +73,14 @@ namespace ICSharpCode.Decompiler.CSharp
expression.Expression.AddAnnotation(resolveResult);
return new ConvertedExpression(expression, resolveResult);
}
+
+ ///
+ /// Retrieves the symbol associated with this AstNode, or null if no symbol is associated with the node.
+ ///
+ public static ISymbol GetSymbol(this AstNode node)
+ {
+ var rr = node.Annotation();
+ return rr != null ? rr.GetSymbol() : null;
+ }
}
}
diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index eccf2463a..9246eb29a 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -16,20 +16,20 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-using ICSharpCode.Decompiler.CSharp.Transforms;
-using ICSharpCode.Decompiler.IL;
-using ICSharpCode.NRefactory.CSharp;
-using ICSharpCode.NRefactory.CSharp.Refactoring;
-using ICSharpCode.NRefactory.TypeSystem;
-using ICSharpCode.NRefactory.TypeSystem.Implementation;
-using ICSharpCode.NRefactory.Utils;
-using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.NRefactory.TypeSystem.Implementation;
+using ICSharpCode.NRefactory.Utils;
+using Mono.Cecil;
+using ICSharpCode.Decompiler.CSharp.Transforms;
+using ICSharpCode.Decompiler.IL;
namespace ICSharpCode.Decompiler.CSharp
{
@@ -40,7 +40,22 @@ namespace ICSharpCode.Decompiler.CSharp
NRefactoryCecilMapper cecilMapper;
ICompilation compilation;
TypeSystemAstBuilder typeSystemAstBuilder;
- List astTransforms = new List(TransformationPipeline.CreatePipeline());
+ List astTransforms = new List {
+ //new PushNegation(),
+ //new DelegateConstruction(context),
+ //new PatternStatementTransform(context),
+ new ReplaceMethodCallsWithOperators(),
+ new IntroduceUnsafeModifier(),
+ new AddCheckedBlocks(),
+ //new DeclareVariables(context), // should run after most transforms that modify statements
+ new ConvertConstructorCallIntoInitializer(), // must run after DeclareVariables
+ //new DecimalConstantTransform(),
+ //new IntroduceUsingDeclarations(context),
+ //new IntroduceExtensionMethods(context), // must run after IntroduceUsingDeclarations
+ //new IntroduceQueryExpressions(context), // must run after IntroduceExtensionMethods
+ //new CombineQueryExpressions(context),
+ //new FlattenSwitchBlocks(),
+ };
public CancellationToken CancellationToken { get; set; }
@@ -84,6 +99,14 @@ namespace ICSharpCode.Decompiler.CSharp
return null;
}
+ void RunTransforms(AstNode rootNode)
+ {
+ var context = new TransformContext(compilation, cecilMapper);
+ foreach (var transform in astTransforms)
+ transform.Run(rootNode, context);
+ rootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
+ }
+
public SyntaxTree DecompileWholeModuleAsSingleFile()
{
SyntaxTree syntaxTree = new SyntaxTree();
@@ -100,10 +123,11 @@ namespace ICSharpCode.Decompiler.CSharp
foreach (var typeDef in g) {
if (typeDef.Name == "" && typeDef.Members.Count == 0)
continue;
- var typeDecl = Decompile(typeDef);
+ var typeDecl = DoDecompile(typeDef);
groupNode.AddChild(typeDecl, SyntaxTree.MemberRole);
}
}
+ RunTransforms(syntaxTree);
return syntaxTree;
}
@@ -114,24 +138,23 @@ namespace ICSharpCode.Decompiler.CSharp
ITypeDefinition typeDef = cecilMapper.GetType(typeDefinition).GetDefinition();
if (typeDef == null)
throw new InvalidOperationException("Could not find type definition in NR type system");
- return Decompile(typeDef);
+ var decl = DoDecompile(typeDef);
+ RunTransforms(decl);
+ return decl;
}
- EntityDeclaration Decompile(ITypeDefinition typeDef)
+ EntityDeclaration DoDecompile(ITypeDefinition typeDef)
{
var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef);
var typeDecl = entityDecl as TypeDeclaration;
- if (typeDecl == null)
- {
+ if (typeDecl == null) {
// e.g. DelegateDeclaration
return entityDecl;
}
- foreach (var method in typeDef.Methods)
- {
+ foreach (var method in typeDef.Methods) {
var methodDef = cecilMapper.GetCecil(method) as MethodDefinition;
- if (methodDef != null)
- {
- var memberDecl = Decompile(methodDef, method);
+ if (methodDef != null) {
+ var memberDecl = DoDecompile(methodDef, method);
typeDecl.Members.Add(memberDecl);
}
}
@@ -145,10 +168,12 @@ namespace ICSharpCode.Decompiler.CSharp
var method = cecilMapper.GetMethod(methodDefinition);
if (method == null)
throw new InvalidOperationException("Could not find method in NR type system");
- return Decompile(methodDefinition, method);
+ var decl = DoDecompile(methodDefinition, method);
+ RunTransforms(decl);
+ return decl;
}
- EntityDeclaration Decompile(MethodDefinition methodDefinition, IMethod method)
+ EntityDeclaration DoDecompile(MethodDefinition methodDefinition, IMethod method)
{
var entityDecl = typeSystemAstBuilder.ConvertEntity(method);
if (methodDefinition.HasBody) {
@@ -159,9 +184,7 @@ namespace ICSharpCode.Decompiler.CSharp
function.CheckInvariant();
var statementBuilder = new StatementBuilder(method, cecilMapper);
var body = statementBuilder.ConvertAsBlock(function.Body);
- foreach (var transform in astTransforms) {
- transform.Run(body);
- }
+
// insert variables at start of body
Statement prevVarDecl = null;
foreach (var v in function.Variables) {
@@ -172,9 +195,7 @@ namespace ICSharpCode.Decompiler.CSharp
prevVarDecl = varDecl;
}
}
- body.AcceptVisitor(new InsertParenthesesVisitor {
- InsertParenthesesForReadability = true
- });
+
entityDecl.AddChild(body, Roles.Body);
}
return entityDecl;
diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs b/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs
index 51b0db29d..edd7fdf94 100644
--- a/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs
+++ b/ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs
@@ -234,12 +234,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
#endregion
- public void Run(AstNode node)
+ public void Run(AstNode node, TransformContext context)
{
BlockStatement block = node as BlockStatement;
if (block == null) {
for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) {
- Run(child);
+ Run(child, context);
}
} else {
Result r = GetResultFromBlock(block);
diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs b/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
index 9af544c0f..4f7304071 100644
--- a/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
+++ b/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
@@ -21,6 +21,8 @@ using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.PatternMatching;
+using ICSharpCode.NRefactory.Semantics;
+using ICSharpCode.NRefactory.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -28,9 +30,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
///
/// If the first element of a constructor is a chained constructor call, convert it into a constructor initializer.
///
- public class ConvertConstructorCallIntoInitializer : DepthFirstAstVisitor