206 lines
9.5 KiB
C#
206 lines
9.5 KiB
C#
using System.Collections.Immutable;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
|
|
internal sealed class SourceCustomEventSymbol : SourceEventSymbol
|
|
{
|
|
private readonly TypeWithAnnotations _type;
|
|
|
|
private readonly string _name;
|
|
|
|
private readonly SourceEventAccessorSymbol? _addMethod;
|
|
|
|
private readonly SourceEventAccessorSymbol? _removeMethod;
|
|
|
|
private readonly TypeSymbol _explicitInterfaceType;
|
|
|
|
private readonly ImmutableArray<EventSymbol> _explicitInterfaceImplementations;
|
|
|
|
public override TypeWithAnnotations TypeWithAnnotations => _type;
|
|
|
|
public override string Name => _name;
|
|
|
|
public override MethodSymbol? AddMethod => _addMethod;
|
|
|
|
public override MethodSymbol? RemoveMethod => _removeMethod;
|
|
|
|
protected override AttributeLocation AllowedAttributeLocations => AttributeLocation.Event;
|
|
|
|
private ExplicitInterfaceSpecifierSyntax? ExplicitInterfaceSpecifier => ((EventDeclarationSyntax)base.CSharpSyntaxNode).ExplicitInterfaceSpecifier;
|
|
|
|
internal override bool IsExplicitInterfaceImplementation => ExplicitInterfaceSpecifier != null;
|
|
|
|
public override ImmutableArray<EventSymbol> ExplicitInterfaceImplementations => _explicitInterfaceImplementations;
|
|
|
|
internal SourceCustomEventSymbol(SourceMemberContainerTypeSymbol containingType, Binder binder, EventDeclarationSyntax syntax, BindingDiagnosticBag diagnostics)
|
|
: base(containingType, syntax, syntax.Modifiers, isFieldLike: false, syntax.ExplicitInterfaceSpecifier, syntax.Identifier, diagnostics)
|
|
{
|
|
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0228: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0271: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0276: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0243: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
|
|
ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier = syntax.ExplicitInterfaceSpecifier;
|
|
SyntaxToken identifier = syntax.Identifier;
|
|
bool flag = explicitInterfaceSpecifier != null;
|
|
_name = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(binder, explicitInterfaceSpecifier, ((SyntaxToken)(ref identifier)).ValueText, diagnostics, out _explicitInterfaceType, out string aliasQualifierOpt);
|
|
_type = BindEventType(binder, syntax.Type, diagnostics);
|
|
EventSymbol eventSymbol = this.FindExplicitlyImplementedEvent(_explicitInterfaceType, ((SyntaxToken)(ref identifier)).ValueText, explicitInterfaceSpecifier, diagnostics);
|
|
this.FindExplicitlyImplementedMemberVerification(eventSymbol, diagnostics);
|
|
if (!flag)
|
|
{
|
|
if (IsOverride)
|
|
{
|
|
EventSymbol overriddenEvent = base.OverriddenEvent;
|
|
if ((object)overriddenEvent != null)
|
|
{
|
|
SourceEventSymbol.CopyEventCustomModifiers(overriddenEvent, ref _type, ContainingAssembly);
|
|
}
|
|
}
|
|
}
|
|
else if ((object)eventSymbol != null)
|
|
{
|
|
SourceEventSymbol.CopyEventCustomModifiers(eventSymbol, ref _type, ContainingAssembly);
|
|
}
|
|
AccessorDeclarationSyntax accessorDeclarationSyntax = null;
|
|
AccessorDeclarationSyntax accessorDeclarationSyntax2 = null;
|
|
if (syntax.AccessorList != null)
|
|
{
|
|
Enumerator<AccessorDeclarationSyntax> enumerator = syntax.AccessorList.Accessors.GetEnumerator();
|
|
SyntaxToken val;
|
|
while (enumerator.MoveNext())
|
|
{
|
|
AccessorDeclarationSyntax current = enumerator.Current;
|
|
bool flag2 = false;
|
|
switch (current.Kind())
|
|
{
|
|
case SyntaxKind.AddAccessorDeclaration:
|
|
if (accessorDeclarationSyntax == null)
|
|
{
|
|
accessorDeclarationSyntax = current;
|
|
flag2 = true;
|
|
}
|
|
else
|
|
{
|
|
val = current.Keyword;
|
|
diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, ((SyntaxToken)(ref val)).GetLocation());
|
|
}
|
|
break;
|
|
case SyntaxKind.RemoveAccessorDeclaration:
|
|
if (accessorDeclarationSyntax2 == null)
|
|
{
|
|
accessorDeclarationSyntax2 = current;
|
|
flag2 = true;
|
|
}
|
|
else
|
|
{
|
|
val = current.Keyword;
|
|
diagnostics.Add(ErrorCode.ERR_DuplicateAccessor, ((SyntaxToken)(ref val)).GetLocation());
|
|
}
|
|
break;
|
|
case SyntaxKind.GetAccessorDeclaration:
|
|
case SyntaxKind.SetAccessorDeclaration:
|
|
case SyntaxKind.InitAccessorDeclaration:
|
|
val = current.Keyword;
|
|
diagnostics.Add(ErrorCode.ERR_AddOrRemoveExpected, ((SyntaxToken)(ref val)).GetLocation());
|
|
break;
|
|
default:
|
|
throw ExceptionUtilities.UnexpectedValue((object)current.Kind());
|
|
case SyntaxKind.UnknownAccessorDeclaration:
|
|
break;
|
|
}
|
|
if (flag2 && !IsAbstract && current.Body == null && current.ExpressionBody == null && current.SemicolonToken.Kind() == SyntaxKind.SemicolonToken)
|
|
{
|
|
val = current.SemicolonToken;
|
|
diagnostics.Add(ErrorCode.ERR_AddRemoveMustHaveBody, ((SyntaxToken)(ref val)).GetLocation());
|
|
}
|
|
}
|
|
if (IsAbstract)
|
|
{
|
|
val = syntax.AccessorList.OpenBraceToken;
|
|
if (!((SyntaxToken)(ref val)).IsMissing)
|
|
{
|
|
val = syntax.AccessorList.OpenBraceToken;
|
|
diagnostics.Add(ErrorCode.ERR_AbstractEventHasAccessors, ((SyntaxToken)(ref val)).GetLocation(), this);
|
|
}
|
|
}
|
|
else if (accessorDeclarationSyntax == null || accessorDeclarationSyntax2 == null)
|
|
{
|
|
val = syntax.AccessorList.OpenBraceToken;
|
|
if (!((SyntaxToken)(ref val)).IsMissing || !flag)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_EventNeedsBothAccessors, GetFirstLocation(), this);
|
|
}
|
|
}
|
|
}
|
|
else if (flag && !IsAbstract)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_ExplicitEventFieldImpl, GetFirstLocation());
|
|
}
|
|
if (flag && IsAbstract && syntax.AccessorList == null)
|
|
{
|
|
Binder.CheckFeatureAvailability((SyntaxNode)(object)syntax, MessageID.IDS_DefaultInterfaceImplementation, diagnostics, GetFirstLocation());
|
|
if (!ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)
|
|
{
|
|
diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, GetFirstLocation());
|
|
}
|
|
_addMethod = new SynthesizedEventAccessorSymbol(this, isAdder: true, isExpressionBodied: false, eventSymbol, aliasQualifierOpt);
|
|
_removeMethod = new SynthesizedEventAccessorSymbol(this, isAdder: false, isExpressionBodied: false, eventSymbol, aliasQualifierOpt);
|
|
}
|
|
else
|
|
{
|
|
_addMethod = CreateAccessorSymbol(DeclaringCompilation, accessorDeclarationSyntax, eventSymbol, aliasQualifierOpt, diagnostics);
|
|
_removeMethod = CreateAccessorSymbol(DeclaringCompilation, accessorDeclarationSyntax2, eventSymbol, aliasQualifierOpt, diagnostics);
|
|
}
|
|
_explicitInterfaceImplementations = (((object)eventSymbol == null) ? ImmutableArray<EventSymbol>.Empty : ImmutableArray.Create(eventSymbol));
|
|
}
|
|
|
|
internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0035: Expected O, but got Unknown
|
|
base.AfterAddingTypeMembersChecks(conversions, diagnostics);
|
|
if ((object)_explicitInterfaceType != null)
|
|
{
|
|
ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier = ExplicitInterfaceSpecifier;
|
|
_explicitInterfaceType.CheckAllConstraints(DeclaringCompilation, conversions, (Location)new SourceLocation((SyntaxNode)(object)explicitInterfaceSpecifier.Name), diagnostics);
|
|
}
|
|
if (!_explicitInterfaceImplementations.IsEmpty)
|
|
{
|
|
EventSymbol interfaceMember = _explicitInterfaceImplementations[0];
|
|
TypeSymbol.CheckModifierMismatchOnImplementingMember(ContainingType, this, interfaceMember, isExplicit: true, diagnostics);
|
|
}
|
|
}
|
|
|
|
[return: NotNullIfNotNull("syntaxOpt")]
|
|
private SourceCustomEventAccessorSymbol? CreateAccessorSymbol(CSharpCompilation compilation, AccessorDeclarationSyntax? syntaxOpt, EventSymbol? explicitlyImplementedEventOpt, string? aliasQualifierOpt, BindingDiagnosticBag diagnostics)
|
|
{
|
|
if (syntaxOpt == null)
|
|
{
|
|
return null;
|
|
}
|
|
return new SourceCustomEventAccessorSymbol(this, syntaxOpt, explicitlyImplementedEventOpt, aliasQualifierOpt, compilation.IsNullableAnalysisEnabledIn((SyntaxNode)(object)syntaxOpt), diagnostics);
|
|
}
|
|
}
|