| File: Symbols\Synthesized\SynthesizedEmbeddedNullableAttributeSymbol.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. #nullable disable using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.CSharp.Symbols { internal sealed class SynthesizedEmbeddedNullableAttributeSymbol : SynthesizedEmbeddedAttributeSymbolBase { private readonly ImmutableArray<FieldSymbol> _fields; private readonly ImmutableArray<MethodSymbol> _constructors; private readonly TypeSymbol _byteTypeSymbol; private const string NullableFlagsFieldName = "NullableFlags"; public SynthesizedEmbeddedNullableAttributeSymbol( string name, NamespaceSymbol containingNamespace, ModuleSymbol containingModule, NamedTypeSymbol systemAttributeType, TypeSymbol systemByteType) : base(name, containingNamespace, containingModule, baseType: systemAttributeType) { _byteTypeSymbol = systemByteType; var annotatedByteType = TypeWithAnnotations.Create(systemByteType); var byteArrayType = TypeWithAnnotations.Create( ArrayTypeSymbol.CreateSZArray( systemByteType.ContainingAssembly, annotatedByteType)); _fields = ImmutableArray.Create<FieldSymbol>( new SynthesizedFieldSymbol( this, byteArrayType.Type, NullableFlagsFieldName, DeclarationModifiers.Public, isReadOnly: true, isStatic: false)); _constructors = ImmutableArray.Create<MethodSymbol>( new SynthesizedEmbeddedAttributeConstructorWithBodySymbol( this, m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, annotatedByteType, 0, RefKind.None)), GenerateSingleByteConstructorBody), new SynthesizedEmbeddedAttributeConstructorWithBodySymbol( this, m => ImmutableArray.Create(SynthesizedParameterSymbol.Create(m, byteArrayType, 0, RefKind.None)), GenerateByteArrayConstructorBody)); // Ensure we never get out of sync with the description Debug.Assert(_constructors.Length == AttributeDescription.NullableAttribute.Signatures.Length); } internal override IEnumerable<FieldSymbol> GetFieldsToEmit() => _fields; public override ImmutableArray<MethodSymbol> Constructors => _constructors; internal override AttributeUsageInfo GetAttributeUsageInfo() { return new AttributeUsageInfo( AttributeTargets.Class | AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.GenericParameter | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, allowMultiple: false, inherited: false); } private void GenerateByteArrayConstructorBody(SyntheticBoundNodeFactory factory, ArrayBuilder<BoundStatement> statements, ImmutableArray<ParameterSymbol> parameters) { statements.Add( factory.ExpressionStatement( factory.AssignmentExpression( factory.Field( factory.This(), _fields.Single()), factory.Parameter(parameters.Single()) ) ) ); } private void GenerateSingleByteConstructorBody(SyntheticBoundNodeFactory factory, ArrayBuilder<BoundStatement> statements, ImmutableArray<ParameterSymbol> parameters) { statements.Add( factory.ExpressionStatement( factory.AssignmentExpression( factory.Field( factory.This(), _fields.Single()), factory.Array( _byteTypeSymbol, ImmutableArray.Create<BoundExpression>( factory.Parameter(parameters.Single()) ) ) ) ) ); } } internal sealed class SynthesizedEmbeddedAttributeConstructorWithBodySymbol : SynthesizedInstanceConstructor { private readonly ImmutableArray<ParameterSymbol> _parameters; private readonly Action<SyntheticBoundNodeFactory, ArrayBuilder<BoundStatement>, ImmutableArray<ParameterSymbol>> _getConstructorBody; internal SynthesizedEmbeddedAttributeConstructorWithBodySymbol( NamedTypeSymbol containingType, Func<MethodSymbol, ImmutableArray<ParameterSymbol>> getParameters, Action<SyntheticBoundNodeFactory, ArrayBuilder<BoundStatement>, ImmutableArray<ParameterSymbol>> getConstructorBody) : base(containingType) { _parameters = getParameters(this); _getConstructorBody = getConstructorBody; } public override ImmutableArray<ParameterSymbol> Parameters => _parameters; internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) { GenerateMethodBodyCore(compilationState, diagnostics); } internal override void GenerateMethodBodyStatements(SyntheticBoundNodeFactory factory, ArrayBuilder<BoundStatement> statements, BindingDiagnosticBag diagnostics) => _getConstructorBody(factory, statements, _parameters); } }