Browse Source

Fixed decompilation of lambda expressions within generic classes.

pull/100/head
Daniel Grunwald 14 years ago
parent
commit
e0fb40fbcc
  1. 5
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 4
      ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs
  3. 12
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  4. 13
      ILSpy/CSharpLanguage.cs

5
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -48,6 +48,11 @@ namespace ICSharpCode.Decompiler.Ast @@ -48,6 +48,11 @@ namespace ICSharpCode.Decompiler.Ast
return true;
if (settings.YieldReturn && YieldReturnDecompiler.IsCompilerGeneratorEnumerator(type))
return true;
} else if (type != null && type.IsCompilerGenerated()) {
if (type.Name.StartsWith("<PrivateImplementationDetails>", StringComparison.Ordinal))
return true;
if (type.Name.StartsWith("<>", StringComparison.Ordinal) && type.Name.Contains("AnonymousType"))
return true;
}
FieldDefinition field = member as FieldDefinition;
if (field != null && field.IsCompilerGenerated()) {

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

@ -108,8 +108,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -108,8 +108,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (!context.Settings.AnonymousMethods)
return false; // anonymous method decompilation is disabled
// Anonymous methods are defined in the same assembly, so there's no need to Resolve().
MethodDefinition method = methodRef as MethodDefinition;
// Anonymous methods are defined in the same assembly
MethodDefinition method = methodRef.ResolveWithinSameModule();
if (!IsAnonymousMethod(context, method))
return false;

12
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -205,11 +205,11 @@ namespace ICSharpCode.Decompiler.ILAst @@ -205,11 +205,11 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression condition = c.Condition.Arguments.Single() as ILExpression;
if (condition == null || condition.Code != ILCode.Ldsfld)
return;
FieldDefinition field = condition.Operand as FieldDefinition; // field is defined in current assembly
FieldDefinition field = ((FieldReference)condition.Operand).ResolveWithinSameModule(); // field is defined in current assembly
if (field == null || !field.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
return;
ILExpression stsfld = c.TrueBlock.Body[0] as ILExpression;
if (!(stsfld != null && stsfld.Code == ILCode.Stsfld && stsfld.Operand == field))
if (!(stsfld != null && stsfld.Code == ILCode.Stsfld && ((FieldReference)stsfld.Operand).ResolveWithinSameModule() == field))
return;
ILExpression newObj = stsfld.Arguments[0];
if (!(newObj.Code == ILCode.Newobj && newObj.Arguments.Count == 2))
@ -218,15 +218,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -218,15 +218,17 @@ namespace ICSharpCode.Decompiler.ILAst
return;
if (newObj.Arguments[1].Code != ILCode.Ldftn)
return;
MethodDefinition anonymousMethod = newObj.Arguments[1].Operand as MethodDefinition; // method is defined in current assembly
MethodDefinition anonymousMethod = ((MethodReference)newObj.Arguments[1].Operand).ResolveWithinSameModule(); // method is defined in current assembly
if (!Ast.Transforms.DelegateConstruction.IsAnonymousMethod(context, anonymousMethod))
return;
ILExpression expr = block.Body.ElementAtOrDefault(i + 1) as ILExpression;
if (expr != null && expr.GetSelfAndChildrenRecursive<ILExpression>().Count(e => e.Code == ILCode.Ldsfld && e.Operand == field) == 1) {
if (expr != null && expr.GetSelfAndChildrenRecursive<ILExpression>().Count(
e => e.Code == ILCode.Ldsfld && ((FieldReference)e.Operand).ResolveWithinSameModule() == field) == 1)
{
foreach (ILExpression parent in expr.GetSelfAndChildrenRecursive<ILExpression>()) {
for (int j = 0; j < parent.Arguments.Count; j++) {
if (parent.Arguments[j].Code == ILCode.Ldsfld && parent.Arguments[j].Operand == field) {
if (parent.Arguments[j].Code == ILCode.Ldsfld && ((FieldReference)parent.Arguments[j].Operand).ResolveWithinSameModule() == field) {
parent.Arguments[j] = newObj;
block.Body.RemoveAt(i);
i -= new ILInlining(method).InlineInto(block, i, aggressive: true);

13
ILSpy/CSharpLanguage.cs

@ -125,6 +125,8 @@ namespace ICSharpCode.ILSpy @@ -125,6 +125,8 @@ namespace ICSharpCode.ILSpy
WriteProjectFile(new TextOutputWriter(output), files, assembly.MainModule);
} else {
foreach (TypeDefinition type in assembly.MainModule.Types) {
if (AstBuilder.MemberIsHidden(type, options.DecompilerSettings))
continue;
AstBuilder codeDomBuilder = CreateAstBuilder(options, type);
codeDomBuilder.AddType(type);
codeDomBuilder.GenerateCode(output, transformAbortCondition);
@ -266,9 +268,18 @@ namespace ICSharpCode.ILSpy @@ -266,9 +268,18 @@ namespace ICSharpCode.ILSpy
#endregion
#region WriteCodeFilesInProject
bool IncludeTypeWhenDecompilingProject(TypeDefinition type, DecompilationOptions options)
{
if (type.Name == "<Module>" || AstBuilder.MemberIsHidden(type, options.DecompilerSettings))
return false;
if (type.Namespace == "XamlGeneratedNamespace" && type.Name == "GeneratedInternalTypeHelper")
return false;
return true;
}
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet<string> directories)
{
var files = assembly.MainModule.Types.Where(t => t.Name != "<Module>").GroupBy(
var files = assembly.MainModule.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
delegate (TypeDefinition type) {
string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension;
if (string.IsNullOrEmpty(type.Namespace)) {

Loading…
Cancel
Save