| File: Symbols\Synthesized\SynthesizedAccessorValueParameterSymbol.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.Collections.Immutable; using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols { /// <summary> /// Represents the compiler generated value parameter for property/event accessor. /// This parameter has no source location/syntax, but may have attributes. /// Attributes with 'param' target specifier on the accessor must be applied to the this parameter. /// </summary> internal abstract class SynthesizedAccessorValueParameterSymbol : SourceComplexParameterSymbolBase { public SynthesizedAccessorValueParameterSymbol(SourceMemberMethodSymbol accessor, int ordinal) : base(accessor, ordinal, RefKind.None, ParameterSymbol.ValueParameterName, accessor.TryGetFirstLocation(), syntaxRef: null, hasParamsModifier: false, isParams: false, isExtensionMethodThis: false, scope: ScopedKind.None) { Debug.Assert(accessor.Locations.Length <= 1); } internal override FlowAnalysisAnnotations FlowAnalysisAnnotations { get { var result = FlowAnalysisAnnotations.None; if (ContainingSymbol is SourcePropertyAccessorSymbol propertyAccessor && propertyAccessor.AssociatedSymbol is SourcePropertySymbolBase property) { if (property.HasDisallowNull) { result |= FlowAnalysisAnnotations.DisallowNull; } if (property.HasAllowNull) { result |= FlowAnalysisAnnotations.AllowNull; } } return result; } } internal override ImmutableHashSet<string> NotNullIfParameterNotNull => ImmutableHashSet<string>.Empty; public override ImmutableArray<CustomModifier> RefCustomModifiers { get { return ImmutableArray<CustomModifier>.Empty; // since RefKind is always None. } } public override bool IsImplicitlyDeclared { get { return true; } } protected override IAttributeTargetSymbol AttributeOwner { get { return (SourceMemberMethodSymbol)this.ContainingSymbol; } } internal override OneOrMany<SyntaxList<AttributeListSyntax>> GetAttributeDeclarations() { // Bind the attributes on the accessor's attribute syntax list with "param" target specifier. var accessor = (SourceMemberMethodSymbol)this.ContainingSymbol; return accessor.GetAttributeDeclarations(); } internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<CSharpAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddSynthesizedFlowAnalysisAttributes(ref attributes); } internal void AddSynthesizedFlowAnalysisAttributes(ref ArrayBuilder<CSharpAttributeData> attributes) { if (ContainingSymbol is SourcePropertyAccessorSymbol { AssociatedSymbol: SourcePropertySymbolBase property }) { var annotations = FlowAnalysisAnnotations; if ((annotations & FlowAnalysisAnnotations.DisallowNull) != 0) { AddSynthesizedAttribute(ref attributes, SynthesizedAttributeData.Create(property.DisallowNullAttributeIfExists)); } if ((annotations & FlowAnalysisAnnotations.AllowNull) != 0) { AddSynthesizedAttribute(ref attributes, SynthesizedAttributeData.Create(property.AllowNullAttributeIfExists)); } } } } internal sealed class SynthesizedPropertyAccessorValueParameterSymbol : SynthesizedAccessorValueParameterSymbol { public SynthesizedPropertyAccessorValueParameterSymbol(SourcePropertyAccessorSymbol accessor, int ordinal) : base(accessor, ordinal) { Debug.Assert(accessor.Locations.Length <= 1); } public override TypeWithAnnotations TypeWithAnnotations => ((PropertySymbol)((SourcePropertyAccessorSymbol)ContainingSymbol).AssociatedSymbol).TypeWithAnnotations; } internal sealed class SynthesizedEventAccessorValueParameterSymbol : SynthesizedAccessorValueParameterSymbol { private SingleInitNullable<TypeWithAnnotations> _lazyParameterType; public SynthesizedEventAccessorValueParameterSymbol(SourceEventAccessorSymbol accessor, int ordinal) : base(accessor, ordinal) { Debug.Assert(accessor.Locations.Length <= 1); } public override TypeWithAnnotations TypeWithAnnotations { get { return _lazyParameterType.Initialize(static (SourceEventAccessorSymbol accessor) => { SourceEventSymbol @event = accessor.AssociatedEvent; if (accessor.MethodKind == MethodKind.EventAdd) { return @event.TypeWithAnnotations; } else if (@event.IsWindowsRuntimeEvent) { TypeSymbol eventTokenType = @event.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationToken); // Use-site info is collected by SourceEventAccessorSymbol.MethodChecks return TypeWithAnnotations.Create(eventTokenType); } else { return @event.TypeWithAnnotations; } }, (SourceEventAccessorSymbol)this.ContainingSymbol); } } } }