diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index 212ad6392..962ebdea0 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -139,6 +139,13 @@ namespace ICSharpCode.Decompiler.CSharp
// e.g. DelegateDeclaration
return entityDecl;
}
+ foreach (var field in typeDef.Fields) {
+ var fieldDef = typeSystem.GetCecil(field) as FieldDefinition;
+ if (fieldDef != null) {
+ var memberDecl = DoDecompile(fieldDef, field, decompilationContext.WithCurrentMember(field));
+ typeDecl.Members.Add(memberDecl);
+ }
+ }
foreach (var method in typeDef.Methods) {
var methodDef = typeSystem.GetCecil(method) as MethodDefinition;
if (methodDef != null) {
@@ -146,6 +153,13 @@ namespace ICSharpCode.Decompiler.CSharp
typeDecl.Members.Add(memberDecl);
}
}
+ foreach (var property in typeDef.Properties) {
+ var propDef = typeSystem.GetCecil(property) as PropertyDefinition;
+ if (propDef != null) {
+ var propDecl = DoDecompile(propDef, property, decompilationContext.WithCurrentMember(property));
+ typeDecl.Members.Add(propDecl);
+ }
+ }
return typeDecl;
}
@@ -168,26 +182,60 @@ namespace ICSharpCode.Decompiler.CSharp
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var entityDecl = typeSystemAstBuilder.ConvertEntity(method);
if (methodDefinition.HasBody) {
- var ilReader = new ILReader(typeSystem);
- var function = ilReader.ReadIL(methodDefinition.Body, CancellationToken);
- function.CheckInvariant();
- function.Body = function.Body.AcceptVisitor(new TransformingVisitor());
- function.CheckInvariant();
- var statementBuilder = new StatementBuilder(decompilationContext);
- var body = statementBuilder.ConvertAsBlock(function.Body);
-
- // insert variables at start of body
- Statement prevVarDecl = null;
- foreach (var v in function.Variables) {
- if (v.Kind == VariableKind.Local) {
- var type = typeSystemAstBuilder.ConvertType(v.Type);
- var varDecl = new VariableDeclarationStatement(type, v.Name);
- body.Statements.InsertAfter(prevVarDecl, varDecl);
- prevVarDecl = varDecl;
- }
+ DecompileBody(methodDefinition, method, entityDecl, decompilationContext, typeSystemAstBuilder);
+ }
+ return entityDecl;
+ }
+
+ void DecompileBody(MethodDefinition methodDefinition, IMethod method, EntityDeclaration entityDecl, ITypeResolveContext decompilationContext, TypeSystemAstBuilder typeSystemAstBuilder)
+ {
+ var ilReader = new ILReader(typeSystem);
+ var function = ilReader.ReadIL(methodDefinition.Body, CancellationToken);
+ function.CheckInvariant();
+ function.Body = function.Body.AcceptVisitor(new TransformingVisitor());
+ function.CheckInvariant();
+ var statementBuilder = new StatementBuilder(decompilationContext, method);
+ var body = statementBuilder.ConvertAsBlock(function.Body);
+
+ // insert variables at start of body
+ Statement prevVarDecl = null;
+ foreach (var v in function.Variables) {
+ if (v.Kind == VariableKind.Local) {
+ var type = typeSystemAstBuilder.ConvertType(v.Type);
+ var varDecl = new VariableDeclarationStatement(type, v.Name);
+ body.Statements.InsertAfter(prevVarDecl, varDecl);
+ prevVarDecl = varDecl;
}
-
- entityDecl.AddChild(body, Roles.Body);
+ }
+
+ entityDecl.AddChild(body, Roles.Body);
+ }
+
+ EntityDeclaration DoDecompile(FieldDefinition fieldDefinition, IField field, ITypeResolveContext decompilationContext)
+ {
+ Debug.Assert(decompilationContext.CurrentMember == field);
+ var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
+ return typeSystemAstBuilder.ConvertEntity(field);
+ }
+
+ EntityDeclaration DoDecompile(PropertyDefinition propertyDefinition, IProperty property, ITypeResolveContext decompilationContext)
+ {
+ Debug.Assert(decompilationContext.CurrentMember == property);
+ var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
+ EntityDeclaration entityDecl = typeSystemAstBuilder.ConvertEntity(property);
+ Accessor getter, setter;
+ if (entityDecl is PropertyDeclaration) {
+ getter = ((PropertyDeclaration)entityDecl).Getter;
+ setter = ((PropertyDeclaration)entityDecl).Setter;
+ } else {
+ getter = ((IndexerDeclaration)entityDecl).Getter;
+ setter = ((IndexerDeclaration)entityDecl).Setter;
+ }
+ if (property.CanGet) {
+ DecompileBody(propertyDefinition.GetMethod, property.Getter, getter, decompilationContext, typeSystemAstBuilder);
+ }
+ if (property.CanSet) {
+ DecompileBody(propertyDefinition.SetMethod, property.Setter, setter, decompilationContext, typeSystemAstBuilder);
}
return entityDecl;
}
diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
index 03f9a918e..380c62d5a 100644
--- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
@@ -32,12 +32,12 @@ namespace ICSharpCode.Decompiler.CSharp
{
readonly ExpressionBuilder exprBuilder;
readonly IMethod currentMethod;
-
- public StatementBuilder(ITypeResolveContext decompilationContext)
+
+ public StatementBuilder(ITypeResolveContext decompilationContext, IMethod currentMethod)
{
- Debug.Assert(decompilationContext != null && decompilationContext.CurrentMember is IMethod);
+ Debug.Assert(decompilationContext != null && currentMethod != null);
this.exprBuilder = new ExpressionBuilder(decompilationContext);
- this.currentMethod = (IMethod)decompilationContext.CurrentMember;
+ this.currentMethod = currentMethod;
}
public Statement Convert(ILInstruction inst)
diff --git a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
index cc9f72417..b84e7c4ef 100644
--- a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
+++ b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
@@ -94,6 +94,7 @@
+
diff --git a/ICSharpCode.Decompiler/Tests/TestCases/PropertiesAndEvents.cs b/ICSharpCode.Decompiler/Tests/TestCases/PropertiesAndEvents.cs
new file mode 100644
index 000000000..dd96da37b
--- /dev/null
+++ b/ICSharpCode.Decompiler/Tests/TestCases/PropertiesAndEvents.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PropertiesAndEvents
+{
+ class Program
+ {
+ public static int Main(string[] args)
+ {
+ Index i = new Index();
+ i.AutoProp = "Name";
+ Console.WriteLine("AutoProp set!");
+ i[0] = 5;
+ i[1] = 2;
+ Console.WriteLine("{0} {1}", i[0], i[5]);
+ Console.WriteLine("PI² = {0}", i.PISquare);
+ return -1;
+ }
+ }
+
+ class Index
+ {
+ int thisValue;
+
+ public int this[int i]
+ {
+ get { Console.WriteLine("get_this({0})", i); return i * i; }
+ set { Console.WriteLine("set_this({0}, {1})", i, value); thisValue = value; }
+ }
+
+ public string AutoProp { get; set; }
+
+ public double PISquare
+ {
+ get { Console.WriteLine("get_PISquare"); return Math.Pow(Math.PI, 2); }
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler/Tests/TestRunner.cs b/ICSharpCode.Decompiler/Tests/TestRunner.cs
index aa195eb20..3e0fd2c84 100644
--- a/ICSharpCode.Decompiler/Tests/TestRunner.cs
+++ b/ICSharpCode.Decompiler/Tests/TestRunner.cs
@@ -46,6 +46,12 @@ namespace ICSharpCode.Decompiler.Tests
TestCompileDecompileCompileOutputAll("CompoundAssignment.cs");
}
+ [Test]
+ public void PropertiesAndEvents()
+ {
+ TestCompileDecompileCompileOutputAll("PropertiesAndEvents.cs");
+ }
+
void TestCompileDecompileCompileOutputAll(string testFileName)
{
TestCompileDecompileCompileOutput(testFileName, CompilerOptions.None);