Browse Source

In debug builds, make intermediate transform steps available as "language".

pull/10/head
Daniel Grunwald 15 years ago
parent
commit
78a2f904c2
  1. 7
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 14
      ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs
  3. 6
      ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs
  4. 11
      ICSharpCode.Decompiler/CecilExtensions.cs
  5. 39
      ILSpy/CSharpLanguage.cs
  6. 8
      ILSpy/Language.cs

7
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -17,7 +17,12 @@ namespace Decompiler
public void GenerateCode(ITextOutput output) public void GenerateCode(ITextOutput output)
{ {
Transforms.TransformationPipeline.RunTransformations(astCompileUnit); GenerateCode(output, null);
}
public void GenerateCode(ITextOutput output, Predicate<IAstVisitor<object, object>> transformAbortCondition)
{
Transforms.TransformationPipeline.RunTransformationsUntil(astCompileUnit, transformAbortCondition);
astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }, null); astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }, null);
var outputFormatter = new TextOutputFormatter(output); var outputFormatter = new TextOutputFormatter(output);

14
ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil; using Mono.Cecil;
@ -93,7 +94,7 @@ namespace Decompiler.Transforms
MethodDefinition method = methodRef as MethodDefinition; MethodDefinition method = methodRef as MethodDefinition;
if (method == null || !method.Name.StartsWith("<", StringComparison.Ordinal)) if (method == null || !method.Name.StartsWith("<", StringComparison.Ordinal))
return false; return false;
if (!(IsCompilerGenerated(method) || IsCompilerGenerated(method.DeclaringType))) if (!(method.IsCompilerGenerated() || method.DeclaringType.IsCompilerGenerated()))
return false; return false;
TypeDefinition methodContainingType = method.DeclaringType; TypeDefinition methodContainingType = method.DeclaringType;
// check that methodContainingType is within containingType // check that methodContainingType is within containingType
@ -125,16 +126,5 @@ namespace Decompiler.Transforms
objectCreateExpression.ReplaceWith(ame); objectCreateExpression.ReplaceWith(ame);
return true; return true;
} }
bool IsCompilerGenerated(ICustomAttributeProvider provider)
{
if (provider.HasCustomAttributes) {
foreach (CustomAttribute a in provider.CustomAttributes) {
if (a.AttributeType.FullName == "System.Runtime.CompilerServices.CompilerGeneratedAttribute")
return true;
}
}
return false;
}
} }
} }

6
ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs

@ -8,7 +8,7 @@ namespace Decompiler.Transforms
{ {
public static class TransformationPipeline public static class TransformationPipeline
{ {
static IAstVisitor<object, object>[] CreatePipeline() public static IAstVisitor<object, object>[] CreatePipeline()
{ {
return new IAstVisitor<object, object>[] { return new IAstVisitor<object, object>[] {
new DelegateConstruction(), new DelegateConstruction(),
@ -19,7 +19,7 @@ namespace Decompiler.Transforms
public static void RunTransformations(AstNode node) public static void RunTransformations(AstNode node)
{ {
RunTransformationsUntil(node, v => false); RunTransformationsUntil(node, null);
} }
public static void RunTransformationsUntil(AstNode node, Predicate<IAstVisitor<object, object>> abortCondition) public static void RunTransformationsUntil(AstNode node, Predicate<IAstVisitor<object, object>> abortCondition)
@ -41,7 +41,7 @@ namespace Decompiler.Transforms
} }
foreach (var visitor in CreatePipeline()) { foreach (var visitor in CreatePipeline()) {
if (abortCondition(visitor)) if (abortCondition != null && abortCondition(visitor))
return; return;
node.AcceptVisitor(visitor, null); node.AcceptVisitor(visitor, null);
} }

11
ICSharpCode.Decompiler/CecilExtensions.cs

@ -158,5 +158,16 @@ namespace ICSharpCode.Decompiler
} }
return accessorMethods; return accessorMethods;
} }
public static bool IsCompilerGenerated(this ICustomAttributeProvider provider)
{
if (provider.HasCustomAttributes) {
foreach (CustomAttribute a in provider.CustomAttributes) {
if (a.AttributeType.FullName == "System.Runtime.CompilerServices.CompilerGeneratedAttribute")
return true;
}
}
return false;
}
} }
} }

39
ILSpy/CSharpLanguage.cs

@ -17,9 +17,11 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Decompiler; using Decompiler;
using Decompiler.Transforms;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil; using Mono.Cecil;
@ -31,8 +33,33 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public class CSharpLanguage : Language public class CSharpLanguage : Language
{ {
string name = "C#";
Predicate<IAstVisitor<object, object>> transformAbortCondition;
public CSharpLanguage()
{
}
#if DEBUG
internal static IEnumerable<CSharpLanguage> GetDebugLanguages()
{
string lastTransformName = "no transforms";
foreach (Type _transformType in TransformationPipeline.CreatePipeline().Select(v => v.GetType()).Distinct()) {
Type transformType = _transformType; // copy for lambda
yield return new CSharpLanguage {
transformAbortCondition = v => transformType.IsInstanceOfType(v),
name = "C# - " + lastTransformName
};
lastTransformName = "after " + transformType.Name;
}
yield return new CSharpLanguage {
name = "C# - " + lastTransformName
};
}
#endif
public override string Name { public override string Name {
get { return "C#"; } get { return name; }
} }
public override string FileExtension { public override string FileExtension {
@ -43,35 +70,35 @@ namespace ICSharpCode.ILSpy
{ {
AstBuilder codeDomBuilder = new AstBuilder(); AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddMethod(method); codeDomBuilder.AddMethod(method);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output, transformAbortCondition);
} }
public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{ {
AstBuilder codeDomBuilder = new AstBuilder(); AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddProperty(property); codeDomBuilder.AddProperty(property);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output, transformAbortCondition);
} }
public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
{ {
AstBuilder codeDomBuilder = new AstBuilder(); AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddField(field); codeDomBuilder.AddField(field);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output, transformAbortCondition);
} }
public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{ {
AstBuilder codeDomBuilder = new AstBuilder(); AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddEvent(ev); codeDomBuilder.AddEvent(ev);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output, transformAbortCondition);
} }
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
{ {
AstBuilder codeDomBuilder = new AstBuilder(); AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddType(type); codeDomBuilder.AddType(type);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output, transformAbortCondition);
} }
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes) public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes)

8
ILSpy/Language.cs

@ -120,11 +120,15 @@ namespace ICSharpCode.ILSpy
/// <summary> /// <summary>
/// A list of all languages. /// A list of all languages.
/// </summary> /// </summary>
public static readonly ReadOnlyCollection<Language> AllLanguages = Array.AsReadOnly( public static readonly ReadOnlyCollection<Language> AllLanguages = new List<Language>(
new Language[] { new Language[] {
new CSharpLanguage(), new CSharpLanguage(),
new ILLanguage(true) new ILLanguage(true)
}); }
#if DEBUG
.Concat(CSharpLanguage.GetDebugLanguages())
#endif
).AsReadOnly();
/// <summary> /// <summary>
/// Gets a language using its name. /// Gets a language using its name.

Loading…
Cancel
Save