diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index 6c35d22a9..387245244 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -176,6 +176,56 @@ namespace ICSharpCode.Decompiler.CSharp
};
}
+ ///
+ /// Decompiles the body of to ILAst for structural analysis,
+ /// e.g. for recognizing compiler-generated code (see RecordDecompiler).
+ /// Runs the IL transform pipeline with a fixed set of decompiler settings, so the
+ /// resulting shape is independent of the user-visible settings, and stops before the
+ /// late transforms (variable naming etc.) that are only needed for code output.
+ ///
+ internal static Block? DecompileBodyForAnalysis(IMethod method, IDecompilerTypeSystem typeSystem, CancellationToken cancellationToken)
+ {
+ if (method.MetadataToken.IsNil)
+ return null;
+ var module = typeSystem.MainModule;
+ var metadata = module.metadata;
+
+ var methodDefHandle = (MethodDefinitionHandle)method.MetadataToken;
+ var methodDef = metadata.GetMethodDefinition(methodDefHandle);
+ if (!methodDef.HasBody())
+ return null;
+
+ var genericContext = new GenericContext(
+ classTypeParameters: method.DeclaringTypeDefinition?.TypeParameters,
+ methodTypeParameters: null);
+ var body = module.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
+ var ilReader = new ILReader(module);
+ var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);
+ var settings = new DecompilerSettings(LanguageVersion.CSharp1);
+ var transforms = GetILTransforms();
+ // Remove the last couple transforms -- we don't need variable names etc. here
+ int lastBlockTransform = transforms.FindLastIndex(t => t is BlockILTransform);
+ transforms.RemoveRange(lastBlockTransform + 1, transforms.Count - (lastBlockTransform + 1));
+ // Use CombineExitsTransform so that "return other != null && ...;" is a single statement even in release builds
+ transforms.Add(new CombineExitsTransform());
+ il.RunTransforms(transforms,
+ new ILTransformContext(il, typeSystem, debugInfo: null, settings) {
+ CancellationToken = cancellationToken
+ });
+ if (il.Body is BlockContainer container)
+ {
+ return container.EntryPoint;
+ }
+ else if (il.Body is Block block)
+ {
+ return block;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
List astTransforms = GetAstTransforms();
public Stepper Stepper { get; set; } = new Stepper();
diff --git a/ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs b/ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs
index 84a80cc18..c676ca8e6 100644
--- a/ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs
@@ -1259,44 +1259,9 @@ namespace ICSharpCode.Decompiler.CSharp
Block? DecompileBody(IMethod method)
{
- if (method == null || method.MetadataToken.IsNil)
- return null;
- var metadata = typeSystem.MainModule.metadata;
-
- var methodDefHandle = (MethodDefinitionHandle)method.MetadataToken;
- var methodDef = metadata.GetMethodDefinition(methodDefHandle);
- if (!methodDef.HasBody())
- return null;
-
- var genericContext = new GenericContext(
- classTypeParameters: recordTypeDef.TypeParameters,
- methodTypeParameters: null);
- var body = typeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
- var ilReader = new ILReader(typeSystem.MainModule);
- var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);
- var settings = new DecompilerSettings(LanguageVersion.CSharp1);
- var transforms = CSharpDecompiler.GetILTransforms();
- // Remove the last couple transforms -- we don't need variable names etc. here
- int lastBlockTransform = transforms.FindLastIndex(t => t is BlockILTransform);
- transforms.RemoveRange(lastBlockTransform + 1, transforms.Count - (lastBlockTransform + 1));
- // Use CombineExitsTransform so that "return other != null && ...;" is a single statement even in release builds
- transforms.Add(new CombineExitsTransform());
- il.RunTransforms(transforms,
- new ILTransformContext(il, typeSystem, debugInfo: null, settings) {
- CancellationToken = cancellationToken
- });
- if (il.Body is BlockContainer container)
- {
- return container.EntryPoint;
- }
- else if (il.Body is Block block)
- {
- return block;
- }
- else
- {
+ if (method == null)
return null;
- }
+ return CSharpDecompiler.DecompileBodyForAnalysis(method, typeSystem, cancellationToken);
}
}
}