Browse Source

Add special cases for fields and constructors back in CSharpLanguage

pull/850/head
Siegfried Pammer 8 years ago
parent
commit
cf9731b262
  1. 8
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 11
      ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
  3. 106
      ILSpy/Languages/CSharpLanguage.cs

8
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -350,6 +350,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -350,6 +350,14 @@ namespace ICSharpCode.Decompiler.CSharp
/// Decompile the specified types and/or members.
/// </summary>
public SyntaxTree Decompile(params IMemberDefinition[] definitions)
{
return Decompile((IList<IMemberDefinition>)definitions);
}
/// <summary>
/// Decompile the specified types and/or members.
/// </summary>
public SyntaxTree Decompile(IList<IMemberDefinition> definitions)
{
if (definitions == null)
throw new ArgumentNullException(nameof(definitions));

11
ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs

@ -41,6 +41,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -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 @@ -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 @@ -155,12 +157,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
}
void RemoveSingleEmptyConstructor(TypeDeclaration typeDeclaration)
internal void RemoveSingleEmptyConstructor(IEnumerable<AstNode> members, ITypeDefinition contextTypeDefinition)
{
var instanceCtors = typeDeclaration.Members.OfType<ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray();
if (contextTypeDefinition == null) return;
var instanceCtors = members.OfType<ConstructorDeclaration>().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();

106
ILSpy/Languages/CSharpLanguage.cs

@ -34,6 +34,7 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -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 @@ -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<IMemberDefinition> 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<MethodDefinition>() == ctorDef) {
if (ctor.GetSymbol() == this.ctor) {
ctorDecl = ctor;
} else {
// remove other ctors
@ -149,15 +145,14 @@ namespace ICSharpCode.ILSpy @@ -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,19 +161,34 @@ namespace ICSharpCode.ILSpy @@ -166,19 +161,34 @@ 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<IMemberDefinition> 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<IMemberDefinition> CollectFieldsAndCtors(TypeDefinition type, bool isStatic)
{
var members = new List<IMemberDefinition>();
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;
}
/// <summary>
@ -186,36 +196,24 @@ namespace ICSharpCode.ILSpy @@ -186,36 +196,24 @@ namespace ICSharpCode.ILSpy
/// </summary>
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<FieldDefinition>() != 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 @@ -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) {

Loading…
Cancel
Save