File: Symbols\Synthesized\SynthesizedSealedPropertyAccessor.cs
Web Access
Project: src\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.
 
#nullable disable
 
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using Cci = Microsoft.Cci;
 
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
    /// <summary>
    /// If a sealed override property defines fewer accessors than the
    /// original virtual property, it is necessary to synthesize a sealed
    /// accessor so that the accessor will not be overridable from metadata.
    /// </summary>
    internal sealed partial class SynthesizedSealedPropertyAccessor : SynthesizedInstanceMethodSymbol
    {
        private readonly PropertySymbol _property;
        private readonly MethodSymbol _overriddenAccessor;
        private readonly ImmutableArray<ParameterSymbol> _parameters;
 
        public SynthesizedSealedPropertyAccessor(PropertySymbol property, MethodSymbol overriddenAccessor)
        {
            Debug.Assert((object)property != null);
            Debug.Assert(property.IsSealed);
            Debug.Assert((object)overriddenAccessor != null);
 
            _property = property;
            _overriddenAccessor = overriddenAccessor;
            _parameters = SynthesizedParameterSymbol.DeriveParameters(overriddenAccessor, this);
        }
 
        internal MethodSymbol OverriddenAccessor
        {
            get
            {
                return _overriddenAccessor;
            }
        }
 
        public override Symbol ContainingSymbol
        {
            get
            {
                return _property.ContainingType;
            }
        }
 
        public override ImmutableArray<Location> Locations
        {
            get
            {
                return ImmutableArray<Location>.Empty;
            }
        }
 
        public override Accessibility DeclaredAccessibility
        {
            get
            {
                Accessibility overriddenAccessibility = _overriddenAccessor.DeclaredAccessibility;
                switch (overriddenAccessibility)
                {
                    case Accessibility.ProtectedOrInternal:
                        if (!this.ContainingAssembly.HasInternalAccessTo(_overriddenAccessor.ContainingAssembly))
                        {
                            // NOTE: Dev10 actually reports ERR_CantChangeAccessOnOverride (CS0507) in this case,
                            // but it's not clear why.  It seems like it would make more sense to just correct
                            // the accessibility of the synthesized override, the same way a programmer would if
                            // it existed in source.
 
                            return Accessibility.Protected;
                        }
                        break;
 
                    case Accessibility.ProtectedAndInternal:
                        if (!this.ContainingAssembly.HasInternalAccessTo(_overriddenAccessor.ContainingAssembly))
                        {
                            // Of course this must trigger an error later, as you cannot override a private
                            // protected member from another assembly.
                            return Accessibility.Private;
                        }
                        break;
                }
 
#if DEBUG
                var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
                Debug.Assert(AccessCheck.IsSymbolAccessible(_overriddenAccessor, this.ContainingType, ref discardedUseSiteInfo));
#endif
                return overriddenAccessibility;
            }
        }
 
        public override bool IsStatic
        {
            get
            {
                return false; //this is an override
            }
        }
 
        public override bool IsAsync
        {
            get
            {
                return false;
            }
        }
 
        public override bool IsVirtual
        {
            get
            {
                return false; //this is an override
            }
        }
 
        internal override Cci.CallingConvention CallingConvention
        {
            get
            {
                return _overriddenAccessor.CallingConvention;
            }
        }
 
        public override MethodKind MethodKind
        {
            get
            {
                return _overriddenAccessor.MethodKind;
            }
        }
 
        public override int Arity
        {
            get
            {
                return 0;
            }
        }
 
        public override bool IsExtensionMethod
        {
            get
            {
                return false;
            }
        }
 
        public override bool HidesBaseMethodsByName
        {
            get
            {
                return false;
            }
        }
 
        public override bool IsVararg
        {
            get
            {
                return _overriddenAccessor.IsVararg;
            }
        }
 
        public override bool ReturnsVoid
        {
            get
            {
                return _overriddenAccessor.ReturnsVoid;
            }
        }
 
        public override RefKind RefKind
        {
            get
            {
                return _overriddenAccessor.RefKind;
            }
        }
 
        public override TypeWithAnnotations ReturnTypeWithAnnotations
        {
            get
            {
                return _overriddenAccessor.ReturnTypeWithAnnotations;
            }
        }
 
        public override FlowAnalysisAnnotations ReturnTypeFlowAnalysisAnnotations => FlowAnalysisAnnotations.None;
 
        public override ImmutableHashSet<string> ReturnNotNullIfParameterNotNull => ImmutableHashSet<string>.Empty;
 
        public override ImmutableArray<TypeWithAnnotations> TypeArgumentsWithAnnotations
        {
            get
            {
                return ImmutableArray<TypeWithAnnotations>.Empty;
            }
        }
 
        public override ImmutableArray<TypeParameterSymbol> TypeParameters
        {
            get
            {
                return ImmutableArray<TypeParameterSymbol>.Empty;
            }
        }
 
        public override ImmutableArray<ParameterSymbol> Parameters
        {
            get
            {
                return _parameters;
            }
        }
 
        internal override bool IsExplicitInterfaceImplementation
        {
            get { return false; }
        }
 
        public override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations
        {
            get
            {
                return ImmutableArray<MethodSymbol>.Empty;
            }
        }
 
        public override ImmutableArray<CustomModifier> RefCustomModifiers
        {
            get
            {
                return _overriddenAccessor.RefCustomModifiers;
            }
        }
 
        public override Symbol AssociatedSymbol
        {
            get
            {
                return _property;
            }
        }
 
        public override bool IsOverride
        {
            get
            {
                return true;
            }
        }
 
        public override bool IsAbstract
        {
            get
            {
                return false;
            }
        }
 
        public override bool IsSealed
        {
            get
            {
                return true;
            }
        }
 
        public override bool IsExtern
        {
            get
            {
                return false;
            }
        }
 
        public override string Name
        {
            get
            {
                return _overriddenAccessor.Name;
            }
        }
 
        internal override bool HasSpecialName
        {
            get
            {
                return true;
            }
        }
 
        internal override System.Reflection.MethodImplAttributes ImplementationAttributes
        {
            get
            {
                return default(System.Reflection.MethodImplAttributes);
            }
        }
 
        internal sealed override bool IsMetadataVirtual(IsMetadataVirtualOption option = IsMetadataVirtualOption.None)
        {
            return true;
        }
 
        internal override bool IsMetadataFinal
        {
            get
            {
                return true;
            }
        }
 
        internal sealed override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false)
        {
            return false;
        }
 
        internal override bool RequiresSecurityObject
        {
            get
            {
                return false;
            }
        }
 
        public override DllImportData GetDllImportData()
        {
            return null;
        }
 
        internal override MarshalPseudoCustomAttributeData ReturnValueMarshallingInformation
        {
            get { return null; }
        }
 
        internal override bool HasDeclarativeSecurity
        {
            get { return false; }
        }
 
        internal override IEnumerable<Microsoft.Cci.SecurityAttribute> GetSecurityInformation()
        {
            throw ExceptionUtilities.Unreachable();
        }
 
        internal override ImmutableArray<string> GetAppliedConditionalSymbols()
        {
            return ImmutableArray<string>.Empty;
        }
    }
}