Files

315 lines
14 KiB
C#
Raw Permalink Normal View History

2026-08-27 10:56:38 -06:00
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.RuntimeMembers;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal readonly struct AsyncMethodBuilderMemberCollection
{
internal readonly NamedTypeSymbol BuilderType;
internal readonly TypeSymbol ResultType;
internal readonly MethodSymbol CreateBuilder;
internal readonly MethodSymbol SetException;
internal readonly MethodSymbol SetResult;
internal readonly MethodSymbol AwaitOnCompleted;
internal readonly MethodSymbol AwaitUnsafeOnCompleted;
internal readonly MethodSymbol Start;
internal readonly MethodSymbol SetStateMachine;
internal readonly PropertySymbol Task;
internal readonly bool CheckGenericMethodConstraints;
private AsyncMethodBuilderMemberCollection(NamedTypeSymbol builderType, TypeSymbol resultType, MethodSymbol createBuilder, MethodSymbol setException, MethodSymbol setResult, MethodSymbol awaitOnCompleted, MethodSymbol awaitUnsafeOnCompleted, MethodSymbol start, MethodSymbol setStateMachine, PropertySymbol task, bool checkGenericMethodConstraints)
{
BuilderType = builderType;
ResultType = resultType;
CreateBuilder = createBuilder;
SetException = setException;
SetResult = setResult;
AwaitOnCompleted = awaitOnCompleted;
AwaitUnsafeOnCompleted = awaitUnsafeOnCompleted;
Start = start;
SetStateMachine = setStateMachine;
Task = task;
CheckGenericMethodConstraints = checkGenericMethodConstraints;
}
internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, TypeMap typeMap, out AsyncMethodBuilderMemberCollection collection)
{
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
if (method.IsIterator)
{
NamedTypeSymbol builderType = F.WellKnownType((WellKnownType)297);
TryGetBuilderMember<MethodSymbol>(F, (WellKnownMember)446, builderType, customBuilder: false, out var symbol);
if ((object)symbol == null)
{
collection = default(AsyncMethodBuilderMemberCollection);
return false;
}
return TryCreate(F, customBuilder: false, builderType, F.SpecialType((SpecialType)6), symbol, null, null, (WellKnownMember)447, (WellKnownMember)448, (WellKnownMember)449, (WellKnownMember)450, null, out collection);
}
if (method.IsAsyncReturningVoid())
{
NamedTypeSymbol builderType2 = F.WellKnownType((WellKnownType)243);
bool customBuilder = false;
TryGetBuilderMember<MethodSymbol>(F, (WellKnownMember)270, builderType2, customBuilder, out var symbol2);
if ((object)symbol2 == null)
{
collection = default(AsyncMethodBuilderMemberCollection);
return false;
}
return TryCreate(F, customBuilder, builderType2, F.SpecialType((SpecialType)6), symbol2, null, (WellKnownMember)271, (WellKnownMember)272, (WellKnownMember)273, (WellKnownMember)274, (WellKnownMember)275, (WellKnownMember)276, out collection);
}
object builderArgument = null;
if (method.IsAsyncEffectivelyReturningTask(F.Compilation))
{
NamedTypeSymbol namedTypeSymbol = (NamedTypeSymbol)method.ReturnType;
MethodSymbol symbol3 = null;
PropertySymbol symbol4 = null;
bool flag = method.HasAsyncMethodBuilderAttribute(out builderArgument);
bool flag2;
object builderArgument2;
if (flag)
{
flag2 = true;
builderArgument2 = builderArgument;
}
else
{
flag2 = namedTypeSymbol.IsCustomTaskType(out builderArgument2);
}
NamedTypeSymbol namedTypeSymbol2;
if (flag2)
{
namedTypeSymbol2 = ValidateBuilderType(F, builderArgument2, namedTypeSymbol.DeclaredAccessibility, isGeneric: false, flag);
if ((object)namedTypeSymbol2 != null)
{
symbol4 = GetCustomTaskProperty(F, namedTypeSymbol2, namedTypeSymbol);
symbol3 = GetCustomCreateMethod(F, namedTypeSymbol2);
}
}
else
{
namedTypeSymbol2 = F.WellKnownType((WellKnownType)244);
TryGetBuilderMember<MethodSymbol>(F, (WellKnownMember)277, namedTypeSymbol2, flag2, out symbol3);
TryGetBuilderMember<PropertySymbol>(F, (WellKnownMember)284, namedTypeSymbol2, flag2, out symbol4);
}
if ((object)namedTypeSymbol2 == null || (object)symbol3 == null || (object)symbol4 == null)
{
collection = default(AsyncMethodBuilderMemberCollection);
return false;
}
return TryCreate(F, flag2, namedTypeSymbol2, F.SpecialType((SpecialType)6), symbol3, symbol4, (WellKnownMember)278, (WellKnownMember)279, (WellKnownMember)280, (WellKnownMember)281, (WellKnownMember)282, (WellKnownMember)283, out collection);
}
if (method.IsAsyncEffectivelyReturningGenericTask(F.Compilation))
{
NamedTypeSymbol namedTypeSymbol3 = (NamedTypeSymbol)method.ReturnType;
TypeSymbol typeSymbol = namedTypeSymbol3.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.Single().Type;
if (typeSymbol.IsDynamic())
{
typeSymbol = F.SpecialType((SpecialType)1);
}
if (typeMap != null)
{
typeSymbol = typeMap.SubstituteType(typeSymbol).Type;
}
namedTypeSymbol3 = namedTypeSymbol3.ConstructedFrom.Construct(typeSymbol);
MethodSymbol symbol5 = null;
PropertySymbol symbol6 = null;
bool flag3 = method.HasAsyncMethodBuilderAttribute(out builderArgument);
bool flag4;
object builderArgument3;
if (flag3)
{
flag4 = true;
builderArgument3 = builderArgument;
}
else
{
flag4 = namedTypeSymbol3.IsCustomTaskType(out builderArgument3);
}
NamedTypeSymbol namedTypeSymbol4;
if (flag4)
{
namedTypeSymbol4 = ValidateBuilderType(F, builderArgument3, namedTypeSymbol3.DeclaredAccessibility, isGeneric: true, flag3);
if ((object)namedTypeSymbol4 != null)
{
namedTypeSymbol4 = namedTypeSymbol4.ConstructedFrom.Construct(typeSymbol);
symbol6 = GetCustomTaskProperty(F, namedTypeSymbol4, namedTypeSymbol3);
symbol5 = GetCustomCreateMethod(F, namedTypeSymbol4);
}
}
else
{
namedTypeSymbol4 = F.WellKnownType((WellKnownType)245);
namedTypeSymbol4 = namedTypeSymbol4.Construct(typeSymbol);
TryGetBuilderMember<MethodSymbol>(F, (WellKnownMember)285, namedTypeSymbol4, flag4, out symbol5);
TryGetBuilderMember<PropertySymbol>(F, (WellKnownMember)292, namedTypeSymbol4, flag4, out symbol6);
}
if ((object)namedTypeSymbol4 == null || (object)symbol6 == null || (object)symbol5 == null)
{
collection = default(AsyncMethodBuilderMemberCollection);
return false;
}
return TryCreate(F, flag4, namedTypeSymbol4, typeSymbol, symbol5, symbol6, (WellKnownMember)286, (WellKnownMember)287, (WellKnownMember)288, (WellKnownMember)289, (WellKnownMember)290, (WellKnownMember)291, out collection);
}
throw ExceptionUtilities.UnexpectedValue((object)method);
}
private static NamedTypeSymbol ValidateBuilderType(SyntheticBoundNodeFactory F, object builderAttributeArgument, Accessibility desiredAccessibility, bool isGeneric, bool forMethodLevelBuilder = false)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (builderAttributeArgument is NamedTypeSymbol namedTypeSymbol && !namedTypeSymbol.IsErrorType() && !namedTypeSymbol.IsVoidType() && (forMethodLevelBuilder || namedTypeSymbol.DeclaredAccessibility == desiredAccessibility))
{
if (isGeneric)
{
if (namedTypeSymbol.IsUnboundGenericType)
{
NamedTypeSymbol containingType = namedTypeSymbol.ContainingType;
if (((object)containingType == null || !containingType.IsGenericType) && namedTypeSymbol.Arity == 1)
{
return namedTypeSymbol;
}
}
F.Diagnostics.Add(ErrorCode.ERR_WrongArityAsyncReturn, F.Syntax.Location, namedTypeSymbol);
return null;
}
if (!namedTypeSymbol.IsGenericType)
{
return namedTypeSymbol;
}
}
F.Diagnostics.Add(ErrorCode.ERR_BadAsyncReturn, F.Syntax.Location);
return null;
}
private static bool TryCreate(SyntheticBoundNodeFactory F, bool customBuilder, NamedTypeSymbol builderType, TypeSymbol resultType, MethodSymbol createBuilderMethod, PropertySymbol taskProperty, WellKnownMember? setException, WellKnownMember setResult, WellKnownMember awaitOnCompleted, WellKnownMember awaitUnsafeOnCompleted, WellKnownMember start, WellKnownMember? setStateMachine, out AsyncMethodBuilderMemberCollection collection)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
if (TryGetBuilderMember<MethodSymbol>(F, setException, builderType, customBuilder, out var symbol) && TryGetBuilderMember<MethodSymbol>(F, setResult, builderType, customBuilder, out var symbol2) && TryGetBuilderMember<MethodSymbol>(F, awaitOnCompleted, builderType, customBuilder, out var symbol3) && TryGetBuilderMember<MethodSymbol>(F, awaitUnsafeOnCompleted, builderType, customBuilder, out var symbol4) && TryGetBuilderMember<MethodSymbol>(F, start, builderType, customBuilder, out var symbol5) && TryGetBuilderMember<MethodSymbol>(F, setStateMachine, builderType, customBuilder, out var symbol6))
{
collection = new AsyncMethodBuilderMemberCollection(builderType, resultType, createBuilderMethod, symbol, symbol2, symbol3, symbol4, symbol5, symbol6, taskProperty, customBuilder);
return true;
}
collection = default(AsyncMethodBuilderMemberCollection);
return false;
}
private static bool TryGetBuilderMember<TSymbol>(SyntheticBoundNodeFactory F, WellKnownMember? member, NamedTypeSymbol builderType, bool customBuilder, out TSymbol symbol) where TSymbol : Symbol
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
if (!member.HasValue)
{
symbol = null;
return true;
}
WellKnownMember value = member.Value;
if (customBuilder)
{
MemberDescriptor descriptor = WellKnownMembers.GetDescriptor(value);
Symbol symbol2 = CSharpCompilation.GetRuntimeMember(builderType.OriginalDefinition, in descriptor, (SignatureComparer<MethodSymbol, FieldSymbol, PropertySymbol, TypeSymbol, ParameterSymbol>)(object)F.Compilation.WellKnownMemberSignatureComparer, null);
if ((object)symbol2 != null)
{
symbol2 = symbol2.SymbolAsMember(builderType);
}
symbol = symbol2 as TSymbol;
}
else
{
symbol = F.WellKnownMember(value, isOptional: true) as TSymbol;
if ((object)symbol != null)
{
symbol = (TSymbol)symbol.SymbolAsMember(builderType);
}
}
if ((object)symbol == null)
{
MemberDescriptor descriptor2 = WellKnownMembers.GetDescriptor(value);
CSDiagnostic cSDiagnostic = new CSDiagnostic((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, customBuilder ? ((object)builderType) : ((object)((MemberDescriptor)(ref descriptor2)).DeclaringTypeMetadataName), descriptor2.Name), F.Syntax.Location);
((BindingDiagnosticBag)F.Diagnostics).Add((Diagnostic)(object)cSDiagnostic);
return false;
}
return true;
}
private static MethodSymbol GetCustomCreateMethod(SyntheticBoundNodeFactory F, NamedTypeSymbol builderType)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Invalid comparison between Unknown and I4
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Invalid comparison between Unknown and I4
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
ImmutableArray<Symbol>.Enumerator enumerator = builderType.GetMembers("Create").GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
if ((int)current.Kind == 9)
{
MethodSymbol methodSymbol = (MethodSymbol)current;
if ((int)methodSymbol.DeclaredAccessibility == 6 && methodSymbol.IsStatic && methodSymbol.ParameterCount == 0 && !methodSymbol.IsGenericMethod && (int)methodSymbol.RefKind == 0 && methodSymbol.ReturnType.Equals(builderType, (TypeCompareKind)63))
{
return methodSymbol;
}
}
}
F.Diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, F.Syntax.Location, builderType, "Create");
return null;
}
private static PropertySymbol GetCustomTaskProperty(SyntheticBoundNodeFactory F, NamedTypeSymbol builderType, NamedTypeSymbol returnType)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Invalid comparison between Unknown and I4
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Invalid comparison between Unknown and I4
ImmutableArray<Symbol>.Enumerator enumerator = builderType.GetMembers("Task").GetEnumerator();
while (enumerator.MoveNext())
{
Symbol current = enumerator.Current;
if ((int)current.Kind != 15)
{
continue;
}
PropertySymbol propertySymbol = (PropertySymbol)current;
if ((int)propertySymbol.DeclaredAccessibility == 6 && !propertySymbol.IsStatic && propertySymbol.ParameterCount == 0)
{
if (!propertySymbol.Type.Equals(returnType, (TypeCompareKind)63))
{
CSDiagnostic cSDiagnostic = new CSDiagnostic((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_BadAsyncMethodBuilderTaskProperty, builderType, returnType, propertySymbol.Type), F.Syntax.Location);
((BindingDiagnosticBag)F.Diagnostics).Add((Diagnostic)(object)cSDiagnostic);
return null;
}
return propertySymbol;
}
}
CSDiagnostic cSDiagnostic2 = new CSDiagnostic((DiagnosticInfo)(object)new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, builderType, "Task"), F.Syntax.Location);
((BindingDiagnosticBag)F.Diagnostics).Add((Diagnostic)(object)cSDiagnostic2);
return null;
}
}