319 lines
17 KiB
C#
319 lines
17 KiB
C#
using System;
|
|
using System.Collections.Immutable;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
|
|
internal abstract class SourceDelegateMethodSymbol : SourceMemberMethodSymbol
|
|
{
|
|
private sealed class Constructor : SourceDelegateMethodSymbol
|
|
{
|
|
public override string Name => ".ctor";
|
|
|
|
protected override bool HasSetsRequiredMembersImpl => false;
|
|
|
|
internal Constructor(SourceMemberContainerTypeSymbol delegateType, TypeWithAnnotations voidType, TypeWithAnnotations objectType, TypeWithAnnotations intPtrType, DelegateDeclarationSyntax syntax)
|
|
: base(delegateType, voidType, syntax, (MethodKind)1, (RefKind)0, DeclarationModifiers.Public)
|
|
{
|
|
InitializeParameters(ImmutableArray.Create(SynthesizedParameterSymbol.Create(this, objectType, 0, (RefKind)0, "object", (ScopedKind)0), SynthesizedParameterSymbol.Create(this, intPtrType, 1, (RefKind)0, "method", (ScopedKind)0)));
|
|
}
|
|
|
|
internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetReturnTypeAttributeDeclarations()
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
|
return OneOrMany.Create<SyntaxList<AttributeListSyntax>>(default(SyntaxList<AttributeListSyntax>));
|
|
}
|
|
|
|
internal override LexicalSortKey GetLexicalSortKey()
|
|
{
|
|
return new LexicalSortKey(syntaxReferenceOpt.GetLocation(), DeclaringCompilation);
|
|
}
|
|
}
|
|
|
|
private sealed class InvokeMethod : SourceDelegateMethodSymbol
|
|
{
|
|
private readonly ImmutableArray<CustomModifier> _refCustomModifiers;
|
|
|
|
public override string Name => "Invoke";
|
|
|
|
public override ImmutableArray<CustomModifier> RefCustomModifiers => _refCustomModifiers;
|
|
|
|
internal InvokeMethod(SourceMemberContainerTypeSymbol delegateType, RefKind refKind, TypeWithAnnotations returnType, DelegateDeclarationSyntax syntax, Binder binder, BindingDiagnosticBag diagnostics)
|
|
: base(delegateType, returnType, syntax, (MethodKind)3, refKind, DeclarationModifiers.Public | DeclarationModifiers.Virtual)
|
|
{
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0050: Invalid comparison between Unknown and I4
|
|
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0048: Expected O, but got Unknown
|
|
SyntaxToken arglistToken;
|
|
ImmutableArray<SourceParameterSymbol> immutableArray = ParameterHelpers.MakeParameters(binder, this, syntax.ParameterList, out arglistToken, diagnostics, allowRefOrOut: true, allowThis: false, addRefReadOnlyModifier: true);
|
|
if (arglistToken.Kind() == SyntaxKind.ArgListKeyword)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, (Location)new SourceLocation(ref arglistToken));
|
|
}
|
|
if ((int)RefKind == 3)
|
|
{
|
|
NamedTypeSymbol wellKnownType = binder.GetWellKnownType((WellKnownType)273, diagnostics, (SyntaxNode)(object)syntax.ReturnType);
|
|
_refCustomModifiers = ImmutableArray.Create<CustomModifier>(CSharpCustomModifier.CreateRequired(wellKnownType));
|
|
}
|
|
else
|
|
{
|
|
_refCustomModifiers = ImmutableArray<CustomModifier>.Empty;
|
|
}
|
|
InitializeParameters(ImmutableArrayExtensions.Cast<SourceParameterSymbol, ParameterSymbol>(immutableArray));
|
|
}
|
|
|
|
internal override LexicalSortKey GetLexicalSortKey()
|
|
{
|
|
return new LexicalSortKey(syntaxReferenceOpt.GetLocation(), DeclaringCompilation);
|
|
}
|
|
|
|
internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003a: Invalid comparison between Unknown and I4
|
|
Location location = ((DelegateDeclarationSyntax)(object)base.SyntaxRef.GetSyntax(default(CancellationToken))).ReturnType.GetLocation();
|
|
CSharpCompilation declaringCompilation = DeclaringCompilation;
|
|
base.AfterAddingTypeMembersChecks(conversions, diagnostics);
|
|
if ((int)RefKind == 3)
|
|
{
|
|
declaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true);
|
|
}
|
|
ParameterHelpers.EnsureRefKindAttributesExist(declaringCompilation, Parameters, diagnostics, modifyCompilation: true);
|
|
if (declaringCompilation.ShouldEmitNativeIntegerAttributes(base.ReturnType))
|
|
{
|
|
declaringCompilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true);
|
|
}
|
|
ParameterHelpers.EnsureNativeIntegerAttributeExists(declaringCompilation, Parameters, diagnostics, modifyCompilation: true);
|
|
ParameterHelpers.EnsureScopedRefAttributeExists(declaringCompilation, Parameters, diagnostics, modifyCompilation: true);
|
|
if (declaringCompilation.ShouldEmitNullableAttributes(this) && ReturnTypeWithAnnotations.NeedsNullableAttribute())
|
|
{
|
|
declaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
|
|
}
|
|
ParameterHelpers.EnsureNullableAttributeExists(declaringCompilation, this, Parameters, diagnostics, modifyCompilation: true);
|
|
}
|
|
}
|
|
|
|
private sealed class BeginInvokeMethod : SourceDelegateMethodSymbol
|
|
{
|
|
public override string Name => "BeginInvoke";
|
|
|
|
internal BeginInvokeMethod(InvokeMethod invoke, TypeWithAnnotations iAsyncResultType, TypeWithAnnotations objectType, TypeWithAnnotations asyncCallbackType, DelegateDeclarationSyntax syntax)
|
|
: base((SourceNamedTypeSymbol)invoke.ContainingType, iAsyncResultType, syntax, (MethodKind)10, (RefKind)0, DeclarationModifiers.Public | DeclarationModifiers.Virtual)
|
|
{
|
|
ArrayBuilder<ParameterSymbol> instance = ArrayBuilder<ParameterSymbol>.GetInstance();
|
|
ImmutableArray<ParameterSymbol>.Enumerator enumerator = invoke.Parameters.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
SourceParameterSymbol sourceParameterSymbol = (SourceParameterSymbol)enumerator.Current;
|
|
SourceDelegateClonedParameterSymbolForBeginAndEndInvoke sourceDelegateClonedParameterSymbolForBeginAndEndInvoke = new SourceDelegateClonedParameterSymbolForBeginAndEndInvoke(sourceParameterSymbol, this, sourceParameterSymbol.Ordinal);
|
|
instance.Add((ParameterSymbol)sourceDelegateClonedParameterSymbolForBeginAndEndInvoke);
|
|
}
|
|
int parameterCount = invoke.ParameterCount;
|
|
instance.Add(SynthesizedParameterSymbol.Create(this, asyncCallbackType, parameterCount, (RefKind)0, GetUniqueParameterName(instance, "callback"), (ScopedKind)0));
|
|
instance.Add(SynthesizedParameterSymbol.Create(this, objectType, parameterCount + 1, (RefKind)0, GetUniqueParameterName(instance, "object"), (ScopedKind)0));
|
|
InitializeParameters(instance.ToImmutableAndFree());
|
|
}
|
|
|
|
internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetReturnTypeAttributeDeclarations()
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
|
return OneOrMany.Create<SyntaxList<AttributeListSyntax>>(default(SyntaxList<AttributeListSyntax>));
|
|
}
|
|
}
|
|
|
|
private sealed class EndInvokeMethod : SourceDelegateMethodSymbol
|
|
{
|
|
private readonly InvokeMethod _invoke;
|
|
|
|
protected override SourceMemberMethodSymbol BoundAttributesSource => _invoke;
|
|
|
|
public override string Name => "EndInvoke";
|
|
|
|
public override ImmutableArray<CustomModifier> RefCustomModifiers => _invoke.RefCustomModifiers;
|
|
|
|
internal EndInvokeMethod(InvokeMethod invoke, TypeWithAnnotations iAsyncResultType, DelegateDeclarationSyntax syntax)
|
|
: base((SourceNamedTypeSymbol)invoke.ContainingType, invoke.ReturnTypeWithAnnotations, syntax, (MethodKind)10, invoke.RefKind, DeclarationModifiers.Public | DeclarationModifiers.Virtual)
|
|
{
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
|
|
_invoke = invoke;
|
|
ArrayBuilder<ParameterSymbol> instance = ArrayBuilder<ParameterSymbol>.GetInstance();
|
|
int num = 0;
|
|
ImmutableArray<ParameterSymbol>.Enumerator enumerator = invoke.Parameters.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
SourceParameterSymbol sourceParameterSymbol = (SourceParameterSymbol)enumerator.Current;
|
|
if ((int)sourceParameterSymbol.RefKind != 0)
|
|
{
|
|
SourceDelegateClonedParameterSymbolForBeginAndEndInvoke sourceDelegateClonedParameterSymbolForBeginAndEndInvoke = new SourceDelegateClonedParameterSymbolForBeginAndEndInvoke(sourceParameterSymbol, this, num++);
|
|
instance.Add((ParameterSymbol)sourceDelegateClonedParameterSymbolForBeginAndEndInvoke);
|
|
}
|
|
}
|
|
instance.Add(SynthesizedParameterSymbol.Create(this, iAsyncResultType, num++, (RefKind)0, GetUniqueParameterName(instance, "result"), (ScopedKind)0));
|
|
InitializeParameters(instance.ToImmutableAndFree());
|
|
}
|
|
}
|
|
|
|
private ImmutableArray<ParameterSymbol> _parameters;
|
|
|
|
private readonly TypeWithAnnotations _returnType;
|
|
|
|
public sealed override ImmutableArray<ParameterSymbol> Parameters => ImmutableArrayExtensions.NullToEmpty<ParameterSymbol>(_parameters);
|
|
|
|
public override ImmutableArray<TypeParameterSymbol> TypeParameters => ImmutableArray<TypeParameterSymbol>.Empty;
|
|
|
|
public sealed override TypeWithAnnotations ReturnTypeWithAnnotations => _returnType;
|
|
|
|
public sealed override bool IsImplicitlyDeclared => true;
|
|
|
|
internal override bool GenerateDebugInfo => false;
|
|
|
|
protected sealed override IAttributeTargetSymbol AttributeOwner => (SourceNamedTypeSymbol)ContainingSymbol;
|
|
|
|
internal sealed override MethodImplAttributes ImplementationAttributes => MethodImplAttributes.CodeTypeMask;
|
|
|
|
protected SourceDelegateMethodSymbol(SourceMemberContainerTypeSymbol delegateType, TypeWithAnnotations returnType, DelegateDeclarationSyntax syntax, MethodKind methodKind, RefKind refKind, DeclarationModifiers declarationModifiers)
|
|
{
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
|
SyntaxReference reference = syntax.GetReference();
|
|
SyntaxToken identifier = syntax.Identifier;
|
|
base._002Ector(delegateType, reference, ((SyntaxToken)(ref identifier)).GetLocation(), isIterator: false, (declarationModifiers: declarationModifiers, flags: SourceMemberMethodSymbol.MakeFlags(methodKind, refKind, declarationModifiers, returnType.IsVoidType(), returnsVoidIsSet: true, isExpressionBodied: false, isExtensionMethod: false, isNullableAnalysisEnabled: false, isVarArg: false, isExplicitInterfaceImplementation: false)));
|
|
_returnType = returnType;
|
|
}
|
|
|
|
internal sealed override ExecutableCodeBinder TryGetBodyBinder(BinderFactory binderFactoryOpt = null, bool ignoreAccessibility = false)
|
|
{
|
|
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs", 37);
|
|
}
|
|
|
|
protected void InitializeParameters(ImmutableArray<ParameterSymbol> parameters)
|
|
{
|
|
_parameters = parameters;
|
|
}
|
|
|
|
internal static void AddDelegateMembers(SourceMemberContainerTypeSymbol delegateType, ArrayBuilder<Symbol> symbols, DelegateDeclarationSyntax syntax, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00f1: Invalid comparison between Unknown and I4
|
|
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0173: Invalid comparison between Unknown and I4
|
|
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0106: Invalid comparison between Unknown and I4
|
|
//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
|
|
Binder binder = delegateType.GetBinder(syntax.ParameterList);
|
|
TypeSyntax returnType = syntax.ReturnType;
|
|
returnType = returnType.SkipScoped(out var _).SkipRefInLocalOrReturn(diagnostics, out var refKind);
|
|
TypeWithAnnotations returnType2 = binder.BindType(returnType, diagnostics);
|
|
TypeWithAnnotations voidType = TypeWithAnnotations.Create(binder.GetSpecialType((SpecialType)6, diagnostics, (SyntaxNode)(object)syntax));
|
|
TypeWithAnnotations objectType = TypeWithAnnotations.Create(binder.GetSpecialType((SpecialType)1, diagnostics, (SyntaxNode)(object)syntax));
|
|
TypeWithAnnotations intPtrType = TypeWithAnnotations.Create(binder.GetSpecialType((SpecialType)21, diagnostics, (SyntaxNode)(object)syntax));
|
|
if (returnType2.IsRestrictedType(ignoreSpanLikeTypes: true))
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, ((SyntaxNode)returnType).Location, returnType2.Type);
|
|
}
|
|
InvokeMethod invokeMethod = new InvokeMethod(delegateType, refKind, returnType2, syntax, binder, diagnostics);
|
|
invokeMethod.CheckDelegateVarianceSafety(diagnostics);
|
|
symbols.Add((Symbol)invokeMethod);
|
|
symbols.Add((Symbol)new Constructor(delegateType, voidType, objectType, intPtrType, syntax));
|
|
if ((int)binder.Compilation.GetSpecialType((SpecialType)42).TypeKind != 6 && (int)binder.Compilation.GetSpecialType((SpecialType)43).TypeKind != 6 && !delegateType.IsCompilationOutputWinMdObj())
|
|
{
|
|
TypeWithAnnotations iAsyncResultType = TypeWithAnnotations.Create(binder.GetSpecialType((SpecialType)42, diagnostics, (SyntaxNode)(object)syntax));
|
|
TypeWithAnnotations asyncCallbackType = TypeWithAnnotations.Create(binder.GetSpecialType((SpecialType)43, diagnostics, (SyntaxNode)(object)syntax));
|
|
symbols.Add((Symbol)new BeginInvokeMethod(invokeMethod, iAsyncResultType, objectType, asyncCallbackType, syntax));
|
|
symbols.Add((Symbol)new EndInvokeMethod(invokeMethod, iAsyncResultType, syntax));
|
|
}
|
|
if ((int)delegateType.DeclaredAccessibility <= 1)
|
|
{
|
|
return;
|
|
}
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = default(CompoundUseSiteInfo<AssemblySymbol>);
|
|
useSiteInfo._002Ector((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics, delegateType.ContainingAssembly);
|
|
if (!delegateType.IsNoMoreVisibleThan(invokeMethod.ReturnTypeWithAnnotations, ref useSiteInfo))
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, delegateType.GetFirstLocation(), delegateType, invokeMethod.ReturnType);
|
|
}
|
|
bool flag = delegateType.HasFileLocalTypes();
|
|
if (!flag && invokeMethod.ReturnType.HasFileLocalTypes())
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_FileTypeDisallowedInSignature, delegateType.GetFirstLocation(), invokeMethod.ReturnType, delegateType);
|
|
}
|
|
for (int i = 0; i < invokeMethod.Parameters.Length; i++)
|
|
{
|
|
ParameterSymbol parameterSymbol = invokeMethod.Parameters[i];
|
|
if (!parameterSymbol.TypeWithAnnotations.IsAtLeastAsVisibleAs(delegateType, ref useSiteInfo))
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_BadVisDelegateParam, delegateType.GetFirstLocation(), delegateType, parameterSymbol.Type);
|
|
}
|
|
else if (!flag && parameterSymbol.Type.HasFileLocalTypes())
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_FileTypeDisallowedInSignature, delegateType.GetFirstLocation(), parameterSymbol.Type, delegateType);
|
|
}
|
|
}
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).Add(delegateType.GetFirstLocation(), useSiteInfo);
|
|
}
|
|
|
|
protected override void MethodChecks(BindingDiagnosticBag diagnostics)
|
|
{
|
|
}
|
|
|
|
public override ImmutableArray<ImmutableArray<TypeWithAnnotations>> GetTypeParameterConstraintTypes()
|
|
{
|
|
return ImmutableArray<ImmutableArray<TypeWithAnnotations>>.Empty;
|
|
}
|
|
|
|
public override ImmutableArray<TypeParameterConstraintKind> GetTypeParameterConstraintKinds()
|
|
{
|
|
return ImmutableArray<TypeParameterConstraintKind>.Empty;
|
|
}
|
|
|
|
internal sealed override OneOrMany<SyntaxList<AttributeListSyntax>> GetAttributeDeclarations()
|
|
{
|
|
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
|
|
return OneOrMany.Create<SyntaxList<AttributeListSyntax>>(((SourceNamedTypeSymbol)ContainingSymbol).GetAttributeDeclarations());
|
|
}
|
|
|
|
internal sealed override AttributeTargets GetAttributeTarget()
|
|
{
|
|
return AttributeTargets.Delegate;
|
|
}
|
|
|
|
private static string GetUniqueParameterName(ArrayBuilder<ParameterSymbol> currentParameters, string name)
|
|
{
|
|
while (!IsUnique(currentParameters, name))
|
|
{
|
|
name = "__" + name;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
private static bool IsUnique(ArrayBuilder<ParameterSymbol> currentParameters, string name)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
Enumerator<ParameterSymbol> enumerator = currentParameters.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
if (string.CompareOrdinal(enumerator.Current.Name, name) == 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|