ns2.1 and TryResolveStateMachineMethod

This commit is contained in:
Bruno Garcia 2021-01-03 12:13:39 -05:00 committed by Ben Adams
parent abdc33477c
commit ded4efd646
3 changed files with 42 additions and 16 deletions

View File

@ -1,4 +1,5 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -15,8 +15,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks> <TargetFrameworks>netstandard2.1;netstandard2.0;net45</TargetFrameworks>
<!--<TargetFrameworks>netstandard2.0;netstandard2.1;net45</TargetFrameworks>-->
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>

View File

@ -804,38 +804,64 @@ namespace System.Diagnostics
return false; return false;
} }
// https://github.com/dotnet/runtime/blob/c985bdcec2a9190e733bcada413a193d5ff60c0d/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs#L375-L430
private static bool TryResolveStateMachineMethod(ref MethodBase method, out Type declaringType) private static bool TryResolveStateMachineMethod(ref MethodBase method, out Type declaringType)
{ {
Debug.Assert(method != null); if (method.DeclaringType is null)
Debug.Assert(method.DeclaringType != null); {
declaringType = null!;
return false;
}
declaringType = method.DeclaringType; declaringType = method.DeclaringType;
var parentType = declaringType.DeclaringType; var parentType = declaringType.DeclaringType;
if (parentType == null) if (parentType is null)
{ {
return false; return false;
} }
var methods = parentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); static MethodInfo[] GetDeclaredMethods(Type type) =>
type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var candidateMethod in methods) var methods = GetDeclaredMethods(parentType);
if (methods == null)
{ {
var attributes = candidateMethod.GetCustomAttributes<StateMachineAttribute>(); return false;
}
foreach (var asma in attributes) foreach (MethodInfo candidateMethod in methods)
{
var attributes = candidateMethod.GetCustomAttributes<StateMachineAttribute>(inherit: false);
// ReSharper disable once ConditionIsAlwaysTrueOrFalse - Taken from CoreFX
if (attributes is null)
{
continue;
}
bool foundAttribute = false, foundIteratorAttribute = false;
foreach (StateMachineAttribute asma in attributes)
{ {
if (asma.StateMachineType == declaringType) if (asma.StateMachineType == declaringType)
{ {
method = candidateMethod; foundAttribute = true;
declaringType = candidateMethod.DeclaringType; foundIteratorAttribute |= asma is IteratorStateMachineAttribute
// Mark the iterator as changed; so it gets the + annotation of the original method #if NETSTANDARD2_1
// async statemachines resolve directly to their builder methods so aren't marked as changed || asma is AsyncIteratorStateMachineAttribute
return asma is IteratorStateMachineAttribute; #endif
;
} }
} }
}
if (foundAttribute)
{
// If this is an iterator (sync or async), mark the iterator as changed, so it gets the + annotation
// of the original method. Non-iterator async state machines resolve directly to their builder methods
// so aren't marked as changed.
method = candidateMethod;
declaringType = candidateMethod.DeclaringType!;
return foundIteratorAttribute;
}
}
return false; return false;
} }