|
|
|
@ -57,9 +57,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -57,9 +57,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
// Inner functions are transformed before outer functions
|
|
|
|
|
foreach (var f in function.Descendants.OfType<ILFunction>()) { |
|
|
|
|
foreach (var v in f.Variables.ToArray()) { |
|
|
|
|
if (HandleMonoStateMachine(function, v, decompilationContext, f)) |
|
|
|
|
if (context.Settings.YieldReturn && HandleMonoStateMachine(function, v, decompilationContext, f)) |
|
|
|
|
continue; |
|
|
|
|
if (IsClosure(v, out ITypeDefinition closureType, out var inst)) { |
|
|
|
|
if ((context.Settings.AnonymousMethods || context.Settings.ExpressionTrees) && IsClosure(v, out ITypeDefinition closureType, out var inst)) { |
|
|
|
|
AddOrUpdateDisplayClass(f, v, closureType, inst, localFunctionClosureParameter: false); |
|
|
|
|
} |
|
|
|
|
if (context.Settings.LocalFunctions && f.Kind == ILFunctionKind.LocalFunction && v.Kind == VariableKind.Parameter && v.Index > -1 && f.Method.Parameters[v.Index.Value] is IParameter p && LocalFunctionDecompiler.IsClosureParameter(p, decompilationContext)) { |
|
|
|
@ -354,7 +354,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -354,7 +354,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
context.Step($"Introduce captured variable for {field.FullName}", inst); |
|
|
|
|
// Introduce a fresh variable for the display class field.
|
|
|
|
|
Debug.Assert(displayClass.Definition == field.DeclaringTypeDefinition); |
|
|
|
|
v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, field.Type, field.Name); |
|
|
|
|
v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, GetVariableTypeFromClosureField(field), field.Name); |
|
|
|
|
v.HasInitialValue = true; |
|
|
|
|
v.CaptureScope = displayClass.CaptureScope; |
|
|
|
|
inst.ReplaceWith(new LdLoca(v).WithILRange(inst)); |
|
|
|
@ -364,5 +364,20 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -364,5 +364,20 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
inst.ReplaceWith(new LdLoca(v).WithILRange(inst)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private IType GetVariableTypeFromClosureField(IField field) |
|
|
|
|
{ |
|
|
|
|
if (!(field.Type is ITypeParameter typeParameter)) |
|
|
|
|
return field.Type; |
|
|
|
|
var rootMethod = context.Function.Method; |
|
|
|
|
if (typeParameter.Owner != field.DeclaringTypeDefinition) |
|
|
|
|
return field.Type; |
|
|
|
|
if (typeParameter.Index >= rootMethod.TypeParameters.Count) { |
|
|
|
|
Debug.Assert(false, "Cannot map display-class type parameter to method type parameter"); |
|
|
|
|
return field.Type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return rootMethod.TypeParameters[typeParameter.Index]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|