| File: Symbols\Retargeting\RetargetingEventSymbol.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// 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. using System; using System.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; using System.Diagnostics; using System.Globalization; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Emit; namespace Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting { internal sealed class RetargetingEventSymbol : WrappedEventSymbol { /// <summary> /// Owning RetargetingModuleSymbol. /// </summary> private readonly RetargetingModuleSymbol _retargetingModule; //we want to compute this lazily since it may be expensive for the underlying symbol private ImmutableArray<EventSymbol> _lazyExplicitInterfaceImplementations; private CachedUseSiteInfo<AssemblySymbol> _lazyCachedUseSiteInfo = CachedUseSiteInfo<AssemblySymbol>.Uninitialized; public RetargetingEventSymbol(RetargetingModuleSymbol retargetingModule, EventSymbol underlyingEvent) : base(underlyingEvent) { RoslynDebug.Assert((object)retargetingModule != null); Debug.Assert(!(underlyingEvent is RetargetingEventSymbol)); _retargetingModule = retargetingModule; } private RetargetingModuleSymbol.RetargetingSymbolTranslator RetargetingTranslator { get { return _retargetingModule.RetargetingTranslator; } } public override TypeWithAnnotations TypeWithAnnotations { get { return this.RetargetingTranslator.Retarget(_underlyingEvent.TypeWithAnnotations, RetargetOptions.RetargetPrimitiveTypesByTypeCode); } } public override MethodSymbol? AddMethod { get { return (object?)_underlyingEvent.AddMethod == null ? null : this.RetargetingTranslator.Retarget(_underlyingEvent.AddMethod); } } public override MethodSymbol? RemoveMethod { get { return (object?)_underlyingEvent.RemoveMethod == null ? null : this.RetargetingTranslator.Retarget(_underlyingEvent.RemoveMethod); } } internal override FieldSymbol? AssociatedField { get { return (object?)_underlyingEvent.AssociatedField == null ? null : this.RetargetingTranslator.Retarget(_underlyingEvent.AssociatedField); } } internal override bool IsExplicitInterfaceImplementation { get { return _underlyingEvent.IsExplicitInterfaceImplementation; } } public override ImmutableArray<EventSymbol> ExplicitInterfaceImplementations { get { if (_lazyExplicitInterfaceImplementations.IsDefault) { ImmutableInterlocked.InterlockedCompareExchange( ref _lazyExplicitInterfaceImplementations, this.RetargetExplicitInterfaceImplementations(), default(ImmutableArray<EventSymbol>)); } return _lazyExplicitInterfaceImplementations; } } private ImmutableArray<EventSymbol> RetargetExplicitInterfaceImplementations() { var impls = _underlyingEvent.ExplicitInterfaceImplementations; if (impls.IsEmpty) { return impls; } // CONSIDER: we could skip the builder until the first time we see a different method after retargeting var builder = ArrayBuilder<EventSymbol>.GetInstance(); for (int i = 0; i < impls.Length; i++) { var retargeted = this.RetargetingTranslator.Retarget(impls[i]); if ((object?)retargeted != null) { builder.Add(retargeted); } } return builder.ToImmutableAndFree(); } public override Symbol? ContainingSymbol { get { return this.RetargetingTranslator.Retarget(_underlyingEvent.ContainingSymbol); } } public override AssemblySymbol ContainingAssembly { get { return _retargetingModule.ContainingAssembly; } } internal override ModuleSymbol ContainingModule { get { return _retargetingModule; } } public override ImmutableArray<CSharpAttributeData> GetAttributes() { return _underlyingEvent.GetAttributes(); } internal override IEnumerable<CSharpAttributeData> GetCustomAttributesToEmit(PEModuleBuilder moduleBuilder) { return this.RetargetingTranslator.RetargetAttributes(_underlyingEvent.GetCustomAttributesToEmit(moduleBuilder)); } internal override CallerUnsafeMode GetCallerUnsafeMode(ConsList<FieldSymbol> fieldsBeingBound) => _underlyingEvent.GetCallerUnsafeMode(fieldsBeingBound); internal override bool MustCallMethodsDirectly { get { return _underlyingEvent.MustCallMethodsDirectly; } } internal override UseSiteInfo<AssemblySymbol> GetUseSiteInfo() { if (!_lazyCachedUseSiteInfo.IsInitialized) { AssemblySymbol primaryDependency = PrimaryDependency; var result = new UseSiteInfo<AssemblySymbol>(primaryDependency); CalculateUseSiteDiagnostic(ref result); _lazyCachedUseSiteInfo.Initialize(primaryDependency, result); } return _lazyCachedUseSiteInfo.ToUseSiteInfo(PrimaryDependency); } internal sealed override CSharpCompilation? DeclaringCompilation // perf, not correctness { get { return null; } } } }