Skip to content

Commit 8d72672

Browse files
Reimplement DecompilerSettings.StaticLocalFunctions (was lost in the refactoring in #2077)
1 parent b4aec9a commit 8d72672

2 files changed

Lines changed: 30 additions & 7 deletions

File tree

ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,27 @@ LocalFunctionMethod ReduceToLocalFunction(IMethod method, int typeParametersToRe
484484
break;
485485
parametersToRemove++;
486486
}
487-
return new LocalFunctionMethod(method, method.Name, parametersToRemove, typeParametersToRemove);
487+
return new LocalFunctionMethod(method, method.Name, CanBeStaticLocalFunction(), parametersToRemove, typeParametersToRemove);
488+
489+
bool CanBeStaticLocalFunction()
490+
{
491+
if (!context.Settings.StaticLocalFunctions)
492+
return false;
493+
// Cannot be static because there are closure parameters that will be removed
494+
if (parametersToRemove > 0)
495+
return false;
496+
// no closure parameters, but static:
497+
// we can safely assume, this local function can be declared static
498+
if (method.IsStatic)
499+
return true;
500+
// the local function is used in conjunction with a lambda, which means,
501+
// it is defined inside the display-class type
502+
var declaringType = method.DeclaringTypeDefinition;
503+
if (!declaringType.IsCompilerGenerated())
504+
return false;
505+
// if there are no instance fields, we can make it a static local function
506+
return !declaringType.GetFields(f => !f.IsStatic).Any();
507+
}
488508
}
489509

490510
static void TransformToLocalFunctionReference(ILFunction function, CallInstruction useSite)

ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ class LocalFunctionMethod : IMethod
3131
{
3232
readonly IMethod baseMethod;
3333

34-
public LocalFunctionMethod(IMethod baseMethod, string name, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters)
34+
public LocalFunctionMethod(IMethod baseMethod, string name, bool isStaticLocalFunction, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters)
3535
{
3636
if (baseMethod == null)
3737
throw new ArgumentNullException(nameof(baseMethod));
3838
this.baseMethod = baseMethod;
3939
this.Name = name;
40+
this.IsStaticLocalFunction = isStaticLocalFunction;
4041
this.NumberOfCompilerGeneratedParameters = numberOfCompilerGeneratedParameters;
4142
this.NumberOfCompilerGeneratedTypeParameters = numberOfCompilerGeneratedTypeParameters;
4243
}
@@ -47,7 +48,8 @@ public bool Equals(IMember obj, TypeVisitor typeNormalization)
4748
return false;
4849
return baseMethod.Equals(other.baseMethod, typeNormalization)
4950
&& NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters
50-
&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters;
51+
&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters
52+
&& IsStaticLocalFunction == other.IsStaticLocalFunction;
5153
}
5254

5355
public override bool Equals(object obj)
@@ -56,7 +58,8 @@ public override bool Equals(object obj)
5658
return false;
5759
return baseMethod.Equals(other.baseMethod)
5860
&& NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters
59-
&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters;
61+
&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters
62+
&& IsStaticLocalFunction == other.IsStaticLocalFunction;
6063
}
6164

6265
public override int GetHashCode()
@@ -66,14 +69,14 @@ public override int GetHashCode()
6669

6770
public override string ToString()
6871
{
69-
return string.Format("[LocalFunctionMethod: ReducedFrom={0}, Name={1}, NumberOfGeneratedParameters={2}, NumberOfCompilerGeneratedTypeParameters={3}]", ReducedFrom, Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);
72+
return string.Format("[LocalFunctionMethod: ReducedFrom={0}, Name={1}, NumberOfGeneratedParameters={2}, NumberOfCompilerGeneratedTypeParameters={3}, IsStaticLocalFunction={4}]", ReducedFrom, Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters, IsStaticLocalFunction);
7073
}
7174

7275
internal int NumberOfCompilerGeneratedParameters { get; }
7376

7477
internal int NumberOfCompilerGeneratedTypeParameters { get; }
7578

76-
internal bool IsStaticLocalFunction => NumberOfCompilerGeneratedParameters == 0 && (baseMethod.IsStatic || (baseMethod.DeclaringTypeDefinition.IsCompilerGenerated() && !baseMethod.DeclaringType.GetFields(f => !f.IsStatic).Any()));
79+
internal bool IsStaticLocalFunction { get; }
7780

7881
public IMember MemberDefinition => this;
7982

@@ -89,7 +92,7 @@ public IMethod Specialize(TypeParameterSubstitution substitution)
8992
{
9093
return new LocalFunctionMethod(
9194
baseMethod.Specialize(substitution),
92-
Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);
95+
Name, IsStaticLocalFunction, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);
9396
}
9497

9598
IMember IMember.Specialize(TypeParameterSubstitution substitution)

0 commit comments

Comments
 (0)