Browse Source

Reimplement DecompilerSettings.StaticLocalFunctions (was lost in the refactoring in #2077)

pull/2081/head
Siegfried Pammer 6 years ago
parent
commit
8d72672e6c
  1. 22
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  2. 15
      ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs

22
ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

@ -484,7 +484,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms
break; break;
parametersToRemove++; parametersToRemove++;
} }
return new LocalFunctionMethod(method, method.Name, parametersToRemove, typeParametersToRemove); return new LocalFunctionMethod(method, method.Name, CanBeStaticLocalFunction(), parametersToRemove, typeParametersToRemove);
bool CanBeStaticLocalFunction()
{
if (!context.Settings.StaticLocalFunctions)
return false;
// Cannot be static because there are closure parameters that will be removed
if (parametersToRemove > 0)
return false;
// no closure parameters, but static:
// we can safely assume, this local function can be declared static
if (method.IsStatic)
return true;
// the local function is used in conjunction with a lambda, which means,
// it is defined inside the display-class type
var declaringType = method.DeclaringTypeDefinition;
if (!declaringType.IsCompilerGenerated())
return false;
// if there are no instance fields, we can make it a static local function
return !declaringType.GetFields(f => !f.IsStatic).Any();
}
} }
static void TransformToLocalFunctionReference(ILFunction function, CallInstruction useSite) static void TransformToLocalFunctionReference(ILFunction function, CallInstruction useSite)

15
ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs

@ -31,12 +31,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
readonly IMethod baseMethod; readonly IMethod baseMethod;
public LocalFunctionMethod(IMethod baseMethod, string name, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters) public LocalFunctionMethod(IMethod baseMethod, string name, bool isStaticLocalFunction, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters)
{ {
if (baseMethod == null) if (baseMethod == null)
throw new ArgumentNullException(nameof(baseMethod)); throw new ArgumentNullException(nameof(baseMethod));
this.baseMethod = baseMethod; this.baseMethod = baseMethod;
this.Name = name; this.Name = name;
this.IsStaticLocalFunction = isStaticLocalFunction;
this.NumberOfCompilerGeneratedParameters = numberOfCompilerGeneratedParameters; this.NumberOfCompilerGeneratedParameters = numberOfCompilerGeneratedParameters;
this.NumberOfCompilerGeneratedTypeParameters = numberOfCompilerGeneratedTypeParameters; this.NumberOfCompilerGeneratedTypeParameters = numberOfCompilerGeneratedTypeParameters;
} }
@ -47,7 +48,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return false; return false;
return baseMethod.Equals(other.baseMethod, typeNormalization) return baseMethod.Equals(other.baseMethod, typeNormalization)
&& NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters && NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters
&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters; && NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters
&& IsStaticLocalFunction == other.IsStaticLocalFunction;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
@ -56,7 +58,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return false; return false;
return baseMethod.Equals(other.baseMethod) return baseMethod.Equals(other.baseMethod)
&& NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters && NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters
&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters; && NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters
&& IsStaticLocalFunction == other.IsStaticLocalFunction;
} }
public override int GetHashCode() public override int GetHashCode()
@ -66,14 +69,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override string ToString() public override string ToString()
{ {
return string.Format("[LocalFunctionMethod: ReducedFrom={0}, Name={1}, NumberOfGeneratedParameters={2}, NumberOfCompilerGeneratedTypeParameters={3}]", ReducedFrom, Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters); return string.Format("[LocalFunctionMethod: ReducedFrom={0}, Name={1}, NumberOfGeneratedParameters={2}, NumberOfCompilerGeneratedTypeParameters={3}, IsStaticLocalFunction={4}]", ReducedFrom, Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters, IsStaticLocalFunction);
} }
internal int NumberOfCompilerGeneratedParameters { get; } internal int NumberOfCompilerGeneratedParameters { get; }
internal int NumberOfCompilerGeneratedTypeParameters { get; } internal int NumberOfCompilerGeneratedTypeParameters { get; }
internal bool IsStaticLocalFunction => NumberOfCompilerGeneratedParameters == 0 && (baseMethod.IsStatic || (baseMethod.DeclaringTypeDefinition.IsCompilerGenerated() && !baseMethod.DeclaringType.GetFields(f => !f.IsStatic).Any())); internal bool IsStaticLocalFunction { get; }
public IMember MemberDefinition => this; public IMember MemberDefinition => this;
@ -89,7 +92,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
return new LocalFunctionMethod( return new LocalFunctionMethod(
baseMethod.Specialize(substitution), baseMethod.Specialize(substitution),
Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters); Name, IsStaticLocalFunction, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);
} }
IMember IMember.Specialize(TypeParameterSubstitution substitution) IMember IMember.Specialize(TypeParameterSubstitution substitution)

Loading…
Cancel
Save