315 lines
14 KiB
C#
315 lines
14 KiB
C#
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;
|
||
|
|
}
|
||
|
|
}
|