|
|
|
@ -455,22 +455,37 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -455,22 +455,37 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
ILFunction ReadLocalFunctionDefinition(ILFunction rootFunction, IMethod targetMethod, int skipCount) |
|
|
|
|
{ |
|
|
|
|
var methodDefinition = context.PEFile.Metadata.GetMethodDefinition((MethodDefinitionHandle)targetMethod.MetadataToken); |
|
|
|
|
if (!methodDefinition.HasBody()) |
|
|
|
|
return null; |
|
|
|
|
var ilReader = context.CreateILReader(); |
|
|
|
|
var body = context.PEFile.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); |
|
|
|
|
var genericContext = GenericContextFromTypeArguments(targetMethod, skipCount); |
|
|
|
|
if (genericContext == null) |
|
|
|
|
return null; |
|
|
|
|
var function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, genericContext.GetValueOrDefault(), ILFunctionKind.LocalFunction, context.CancellationToken); |
|
|
|
|
ILFunction function; |
|
|
|
|
bool hasBody = methodDefinition.HasBody(); |
|
|
|
|
if (!hasBody) |
|
|
|
|
{ |
|
|
|
|
function = new ILFunction(targetMethod, 0, |
|
|
|
|
new TypeSystem.GenericContext(genericContext?.ClassTypeParameters, genericContext?.MethodTypeParameters), |
|
|
|
|
new Nop(), ILFunctionKind.LocalFunction); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
var ilReader = context.CreateILReader(); |
|
|
|
|
var body = context.PEFile.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); |
|
|
|
|
|
|
|
|
|
function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, |
|
|
|
|
genericContext.GetValueOrDefault(), ILFunctionKind.LocalFunction, |
|
|
|
|
context.CancellationToken); |
|
|
|
|
} |
|
|
|
|
// Embed the local function into the parent function's ILAst, so that "Show steps" can show
|
|
|
|
|
// how the local function body is being transformed.
|
|
|
|
|
rootFunction.LocalFunctions.Add(function); |
|
|
|
|
function.DeclarationScope = (BlockContainer)rootFunction.Body; |
|
|
|
|
function.CheckInvariant(ILPhase.Normal); |
|
|
|
|
var nestedContext = new ILTransformContext(context, function); |
|
|
|
|
function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is LocalFunctionDecompiler)), nestedContext); |
|
|
|
|
function.DeclarationScope = null; |
|
|
|
|
if (hasBody) |
|
|
|
|
{ |
|
|
|
|
function.DeclarationScope = (BlockContainer)rootFunction.Body; |
|
|
|
|
function.CheckInvariant(ILPhase.Normal); |
|
|
|
|
var nestedContext = new ILTransformContext(context, function); |
|
|
|
|
function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is LocalFunctionDecompiler)), nestedContext); |
|
|
|
|
function.DeclarationScope = null; |
|
|
|
|
} |
|
|
|
|
function.ReducedMethod = ReduceToLocalFunction(function.Method, skipCount); |
|
|
|
|
return function; |
|
|
|
|
} |
|
|
|
|