diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index 7eee97087..743aaae17 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -345,11 +345,19 @@ namespace ICSharpCode.Decompiler.CSharp
RunTransforms(syntaxTree, decompilationContext);
return syntaxTree;
}
-
+
///
/// Decompile the specified types and/or members.
///
public SyntaxTree Decompile(params IMemberDefinition[] definitions)
+ {
+ return Decompile((IList)definitions);
+ }
+
+ ///
+ /// Decompile the specified types and/or members.
+ ///
+ public SyntaxTree Decompile(IList definitions)
{
if (definitions == null)
throw new ArgumentNullException(nameof(definitions));
diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs b/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
index d345190b0..31bf900ec 100644
--- a/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
+++ b/ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
@@ -41,6 +41,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
visitor.HandleStaticFieldInitializers(node.Children);
node.AcceptVisitor(visitor);
+
+ visitor.RemoveSingleEmptyConstructor(node.Children, context.DecompiledTypeDefinition);
}
}
@@ -103,7 +105,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
base.VisitTypeDeclaration(typeDeclaration);
// Remove single empty constructor:
- RemoveSingleEmptyConstructor(typeDeclaration);
+ RemoveSingleEmptyConstructor(typeDeclaration.Members, (ITypeDefinition)typeDeclaration.GetSymbol());
// Handle initializers on static fields:
HandleStaticFieldInitializers(typeDeclaration.Members);
@@ -155,12 +157,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
}
- void RemoveSingleEmptyConstructor(TypeDeclaration typeDeclaration)
+ internal void RemoveSingleEmptyConstructor(IEnumerable members, ITypeDefinition contextTypeDefinition)
{
- var instanceCtors = typeDeclaration.Members.OfType().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray();
+ if (contextTypeDefinition == null) return;
+ var instanceCtors = members.OfType().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray();
if (instanceCtors.Length == 1) {
ConstructorDeclaration emptyCtor = new ConstructorDeclaration();
- emptyCtor.Modifiers = ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public);
+ emptyCtor.Modifiers = contextTypeDefinition.IsAbstract ? Modifiers.Protected : Modifiers.Public;
emptyCtor.Body = new BlockStatement();
if (emptyCtor.IsMatch(instanceCtors[0]))
instanceCtors[0].Remove();
diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs
index e3a642d81..6c3cc02f1 100644
--- a/ILSpy/Languages/CSharpLanguage.cs
+++ b/ILSpy/Languages/CSharpLanguage.cs
@@ -34,6 +34,7 @@ using ICSharpCode.Decompiler.TypeSystem;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.Decompiler.CSharp.Transforms;
namespace ICSharpCode.ILSpy
{
@@ -108,36 +109,31 @@ namespace ICSharpCode.ILSpy
AddReferenceWarningMessage(method.Module.Assembly, output);
WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(method.Module, options);
- WriteCode(output, options.DecompilerSettings, decompiler.Decompile(method), decompiler.TypeSystem);
- /*
- AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: method.DeclaringType, isSingleMember: true);
- if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) {
- // also fields and other ctors so that the field initializers can be shown as such
- AddFieldsAndCtors(codeDomBuilder, method.DeclaringType, method.IsStatic);
- RunTransformsAndGenerateCode(codeDomBuilder, output, options, new SelectCtorTransform(method));
+ if (method.IsConstructor && !method.DeclaringType.IsValueType) {
+ List members = CollectFieldsAndCtors(method.DeclaringType, method.IsStatic);
+ decompiler.AstTransforms.Add(new SelectCtorTransform(decompiler.TypeSystem.Resolve(method)));
+ WriteCode(output, options.DecompilerSettings, decompiler.Decompile(members), decompiler.TypeSystem);
} else {
- codeDomBuilder.AddMethod(method);
- RunTransformsAndGenerateCode(codeDomBuilder, output, options);
- }*/
+ WriteCode(output, options.DecompilerSettings, decompiler.Decompile(method), decompiler.TypeSystem);
+ }
}
- /*
class SelectCtorTransform : IAstTransform
{
- readonly MethodDefinition ctorDef;
+ readonly IMethod ctor;
- public SelectCtorTransform(MethodDefinition ctorDef)
+ public SelectCtorTransform(IMethod ctor)
{
- this.ctorDef = ctorDef;
+ this.ctor = ctor;
}
-
- public void Run(AstNode compilationUnit)
+
+ public void Run(AstNode rootNode, TransformContext context)
{
ConstructorDeclaration ctorDecl = null;
- foreach (var node in compilationUnit.Children) {
+ foreach (var node in rootNode.Children) {
ConstructorDeclaration ctor = node as ConstructorDeclaration;
if (ctor != null) {
- if (ctor.Annotation() == ctorDef) {
+ if (ctor.GetSymbol() == this.ctor) {
ctorDecl = ctor;
} else {
// remove other ctors
@@ -149,15 +145,14 @@ namespace ICSharpCode.ILSpy
if (fd != null && fd.Variables.All(v => v.Initializer.IsNull))
fd.Remove();
}
- if (ctorDecl.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) {
+ if (ctorDecl?.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) {
// remove all fields
- foreach (var node in compilationUnit.Children)
+ foreach (var node in rootNode.Children)
if (node is FieldDeclaration)
node.Remove();
}
}
}
- */
public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
@@ -166,56 +161,59 @@ namespace ICSharpCode.ILSpy
CSharpDecompiler decompiler = CreateDecompiler(property.Module, options);
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(property), decompiler.TypeSystem);
}
- /*
+
public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
{
- AddReferenceWarningMessage(output);
+ AddReferenceWarningMessage(field.Module.Assembly, output);
WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true));
- AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: field.DeclaringType, isSingleMember: true);
+ CSharpDecompiler decompiler = CreateDecompiler(field.Module, options);
if (field.IsLiteral) {
- codeDomBuilder.AddField(field);
+ WriteCode(output, options.DecompilerSettings, decompiler.Decompile(field), decompiler.TypeSystem);
} else {
- // also decompile ctors so that the field initializer can be shown
- AddFieldsAndCtors(codeDomBuilder, field.DeclaringType, field.IsStatic);
+ List members = CollectFieldsAndCtors(field.DeclaringType, field.IsStatic);
+ decompiler.AstTransforms.Add(new SelectFieldTransform(decompiler.TypeSystem.Resolve(field)));
+ WriteCode(output, options.DecompilerSettings, decompiler.Decompile(members), decompiler.TypeSystem);
}
- RunTransformsAndGenerateCode(codeDomBuilder, output, options, new SelectFieldTransform(field));
}
-
+
+ private static List CollectFieldsAndCtors(TypeDefinition type, bool isStatic)
+ {
+ var members = new List();
+ foreach (var field in type.Fields) {
+ if (field.IsStatic == isStatic)
+ members.Add(field);
+ }
+ foreach (var ctor in type.Methods) {
+ if (ctor.IsConstructor && ctor.IsStatic == isStatic)
+ members.Add(ctor);
+ }
+
+ return members;
+ }
+
///
/// Removes all top-level members except for the specified fields.
///
sealed class SelectFieldTransform : IAstTransform
{
- readonly FieldDefinition field;
+ readonly IField field;
- public SelectFieldTransform(FieldDefinition field)
+ public SelectFieldTransform(IField field)
{
this.field = field;
}
-
- public void Run(AstNode compilationUnit)
+
+ public void Run(AstNode rootNode, TransformContext context)
{
- foreach (var child in compilationUnit.Children) {
+ foreach (var child in rootNode.Children) {
if (child is EntityDeclaration) {
- if (child.Annotation() != field)
+ if (child.GetSymbol() != field)
child.Remove();
}
}
}
}
-
- void AddFieldsAndCtors(AstBuilder codeDomBuilder, TypeDefinition declaringType, bool isStatic)
- {
- foreach (var field in declaringType.Fields) {
- if (field.IsStatic == isStatic)
- codeDomBuilder.AddField(field);
- }
- foreach (var ctor in declaringType.Methods) {
- if (ctor.IsConstructor && ctor.IsStatic == isStatic)
- codeDomBuilder.AddMethod(ctor);
- }
- }
- */
+
public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
AddReferenceWarningMessage(ev.Module.Assembly, output);
@@ -232,26 +230,6 @@ namespace ICSharpCode.ILSpy
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type), decompiler.TypeSystem);
}
- /*
- void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, IAstTransform additionalTransform = null)
- {
- astBuilder.RunTransformations(transformAbortCondition);
- if (additionalTransform != null) {
- additionalTransform.Run(astBuilder.SyntaxTree);
- }
- if (options.DecompilerSettings.ShowXmlDocumentation) {
- try {
- AddXmlDocTransform.Run(astBuilder.SyntaxTree);
- } catch (XmlException ex) {
- string[] msg = (" Exception while reading XmlDoc: " + ex.ToString()).Split(new[]{'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
- var insertionPoint = astBuilder.SyntaxTree.FirstChild;
- for (int i = 0; i < msg.Length; i++)
- astBuilder.SyntaxTree.InsertChildBefore(insertionPoint, new Comment(msg[i], CommentType.Documentation), Roles.Comment);
- }
- }
- astBuilder.GenerateCode(output);
- }*/
-
public static string GetPlatformDisplayName(ModuleDefinition module)
{
switch (module.Architecture) {