| File: Emit\NoPia\CommonEmbeddedEvent.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Collections.Generic; using System.Diagnostics; using System.Threading; using Cci = Microsoft.Cci; namespace Microsoft.CodeAnalysis.Emit.NoPia { internal abstract partial class EmbeddedTypesManager< TPEModuleBuilder, TModuleCompilationState, TEmbeddedTypesManager, TSyntaxNode, TAttributeData, TSymbol, TAssemblySymbol, TNamedTypeSymbol, TFieldSymbol, TMethodSymbol, TEventSymbol, TPropertySymbol, TParameterSymbol, TTypeParameterSymbol, TEmbeddedType, TEmbeddedField, TEmbeddedMethod, TEmbeddedEvent, TEmbeddedProperty, TEmbeddedParameter, TEmbeddedTypeParameter> { internal abstract class CommonEmbeddedEvent : CommonEmbeddedMember<TEventSymbol>, Cci.IEventDefinition { private readonly TEmbeddedMethod _adder; private readonly TEmbeddedMethod _remover; private readonly TEmbeddedMethod _caller; private int _isUsedForComAwareEventBinding; protected CommonEmbeddedEvent(TEventSymbol underlyingEvent, TEmbeddedMethod adder, TEmbeddedMethod remover, TEmbeddedMethod caller) : base(underlyingEvent) { Debug.Assert(adder != null || remover != null); _adder = adder; _remover = remover; _caller = caller; } internal override TEmbeddedTypesManager TypeManager { get { return AnAccessor.TypeManager; } } protected abstract bool IsRuntimeSpecial { get; } protected abstract bool IsSpecialName { get; } protected abstract Cci.ITypeReference GetType(TPEModuleBuilder moduleBuilder, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics); protected abstract TEmbeddedType ContainingType { get; } protected abstract Cci.TypeMemberVisibility Visibility { get; } protected abstract string Name { get; } public TEventSymbol UnderlyingEvent { get { return this.UnderlyingSymbol; } } protected abstract void EmbedCorrespondingComEventInterfaceMethodInternal(TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics, bool isUsedForComAwareEventBinding); internal void EmbedCorrespondingComEventInterfaceMethod(TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics, bool isUsedForComAwareEventBinding) { if (_isUsedForComAwareEventBinding == 0 && (!isUsedForComAwareEventBinding || Interlocked.CompareExchange(ref _isUsedForComAwareEventBinding, 1, 0) == 0)) { Debug.Assert(!isUsedForComAwareEventBinding || _isUsedForComAwareEventBinding != 0); EmbedCorrespondingComEventInterfaceMethodInternal(syntaxNodeOpt, diagnostics, isUsedForComAwareEventBinding); } Debug.Assert(!isUsedForComAwareEventBinding || _isUsedForComAwareEventBinding != 0); } Cci.IMethodReference Cci.IEventDefinition.Adder { get { return _adder; } } Cci.IMethodReference Cci.IEventDefinition.Remover { get { return _remover; } } Cci.IMethodReference Cci.IEventDefinition.Caller { get { return _caller; } } IEnumerable<Cci.IMethodReference> Cci.IEventDefinition.GetAccessors(EmitContext context) { if (_adder != null) { yield return _adder; } if (_remover != null) { yield return _remover; } if (_caller != null) { yield return _caller; } } bool Cci.IEventDefinition.IsRuntimeSpecial { get { return IsRuntimeSpecial; } } bool Cci.IEventDefinition.IsSpecialName { get { return IsSpecialName; } } Cci.ITypeReference Cci.IEventDefinition.GetType(EmitContext context) { return GetType((TPEModuleBuilder)context.Module, (TSyntaxNode)context.SyntaxNode, context.Diagnostics); } protected TEmbeddedMethod AnAccessor { get { return _adder ?? _remover; } } Cci.ITypeDefinition Cci.ITypeDefinitionMember.ContainingTypeDefinition { get { return ContainingType; } } Cci.TypeMemberVisibility Cci.ITypeDefinitionMember.Visibility { get { return Visibility; } } Cci.ITypeReference Cci.ITypeMemberReference.GetContainingType(EmitContext context) { return ContainingType; } void Cci.IReference.Dispatch(Cci.MetadataVisitor visitor) { visitor.Visit((Cci.IEventDefinition)this); } Cci.IDefinition Cci.IReference.AsDefinition(EmitContext context) { return this; } string Cci.INamedEntity.Name { get { return Name; } } } } }