Skip to content
Permalink
Browse files

Include AttributeUsageAttribute with synthesized nullable attributes (#…

  • Loading branch information...
cston committed Jul 10, 2019
1 parent 5ef45ba commit 3272de5080b2910454f7ae4d57a24e373638c797
@@ -16,10 +16,11 @@ namespace System.Runtime.CompilerServices
AttributeTargets.Parameter |
AttributeTargets.Property |
AttributeTargets.ReturnValue,
AllowMultiple = false)]
AllowMultiple = false,
Inherited = false)]
public sealed class NullableAttribute : Attribute
{
public readonly byte[] Flags;
public readonly byte[] NullableFlags;
public NullableAttribute(byte flag)
{
Flags = new byte[] { flag };
@@ -700,6 +700,18 @@ internal SynthesizedAttributeData SynthesizeTupleNamesAttribute(TypeSymbol type)
return TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_TupleElementNamesAttribute__ctorTransformNames, args);
}

internal SynthesizedAttributeData SynthesizeAttributeUsageAttribute(AttributeTargets targets, bool allowMultiple, bool inherited)
{
var attributeTargetsType = GetWellKnownType(WellKnownType.System_AttributeTargets);
var boolType = GetSpecialType(SpecialType.System_Boolean);
var arguments = ImmutableArray.Create(
new TypedConstant(attributeTargetsType, TypedConstantKind.Enum, targets));
var namedArguments = ImmutableArray.Create(
new KeyValuePair<WellKnownMember, TypedConstant>(WellKnownMember.System_AttributeUsageAttribute__AllowMultiple, new TypedConstant(boolType, TypedConstantKind.Primitive, allowMultiple)),
new KeyValuePair<WellKnownMember, TypedConstant>(WellKnownMember.System_AttributeUsageAttribute__Inherited, new TypedConstant(boolType, TypedConstantKind.Primitive, inherited)));
return TrySynthesizeAttribute(WellKnownMember.System_AttributeUsageAttribute__ctor, arguments, namedArguments);
}

internal static class TupleNamesEncoder
{
public static ImmutableArray<string> Encode(TypeSymbol type)
@@ -27,21 +27,29 @@ internal abstract class SynthesizedEmbeddedAttributeSymbolBase : NamedTypeSymbol
private readonly NamedTypeSymbol _baseType;
private readonly NamespaceSymbol _namespace;
private readonly ModuleSymbol _module;
private readonly bool _includeAttributeUsageAttribute;

public SynthesizedEmbeddedAttributeSymbolBase(
AttributeDescription description,
CSharpCompilation compilation,
DiagnosticBag diagnostics)
DiagnosticBag diagnostics,
bool includeAttributeUsageAttribute)
{
_name = description.Name;
_baseType = MakeBaseType(compilation, diagnostics);
_module = compilation.SourceModule;
_includeAttributeUsageAttribute = includeAttributeUsageAttribute;

_namespace = _module.GlobalNamespace;
foreach (var part in description.Namespace.Split('.'))
{
_namespace = new MissingNamespaceSymbol(_namespace, part);
}

if (includeAttributeUsageAttribute)
{
EnsureAttributeUsageAttribute(compilation, diagnostics);
}
}

private static NamedTypeSymbol MakeBaseType(CSharpCompilation compilation, DiagnosticBag diagnostics)
@@ -166,6 +174,21 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
AddSynthesizedAttribute(
ref attributes,
moduleBuilder.SynthesizeEmbeddedAttribute());

if (_includeAttributeUsageAttribute)
{
var usageInfo = GetAttributeUsageInfo();
AddSynthesizedAttribute(
ref attributes,
moduleBuilder.Compilation.SynthesizeAttributeUsageAttribute(usageInfo.ValidTargets, usageInfo.AllowMultiple, usageInfo.Inherited));
}
}

private static void EnsureAttributeUsageAttribute(CSharpCompilation compilation, DiagnosticBag diagnostics)
{
Binder.GetWellKnownTypeMember(compilation, WellKnownMember.System_AttributeUsageAttribute__ctor, diagnostics, Location.None);
Binder.GetWellKnownTypeMember(compilation, WellKnownMember.System_AttributeUsageAttribute__AllowMultiple, diagnostics, Location.None);
Binder.GetWellKnownTypeMember(compilation, WellKnownMember.System_AttributeUsageAttribute__Inherited, diagnostics, Location.None);
}
}

@@ -180,7 +203,7 @@ internal sealed class SynthesizedEmbeddedAttributeSymbol : SynthesizedEmbeddedAt
AttributeDescription description,
CSharpCompilation compilation,
DiagnosticBag diagnostics)
: base(description, compilation, diagnostics)
: base(description, compilation, diagnostics, includeAttributeUsageAttribute: false)
{
_constructors = ImmutableArray.Create<MethodSymbol>(new SynthesizedEmbeddedAttributeConstructorSymbol(this, m => ImmutableArray<ParameterSymbol>.Empty));
Debug.Assert(_constructors.Length == description.Signatures.Length);
@@ -22,7 +22,7 @@ internal sealed class SynthesizedEmbeddedNullableAttributeSymbol : SynthesizedEm
public SynthesizedEmbeddedNullableAttributeSymbol(
CSharpCompilation compilation,
DiagnosticBag diagnostics)
: base(AttributeDescription.NullableAttribute, compilation, diagnostics)
: base(AttributeDescription.NullableAttribute, compilation, diagnostics, includeAttributeUsageAttribute: true)
{
var byteType = TypeWithAnnotations.Create(compilation.GetSpecialType(SpecialType.System_Byte));
_byteTypeSymbol = byteType.Type;
@@ -63,6 +63,14 @@ internal sealed class SynthesizedEmbeddedNullableAttributeSymbol : SynthesizedEm

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(
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
@@ -16,7 +17,7 @@ internal sealed class SynthesizedEmbeddedNullableContextAttributeSymbol : Synthe
public SynthesizedEmbeddedNullableContextAttributeSymbol(
CSharpCompilation compilation,
DiagnosticBag diagnostics)
: base(AttributeDescription.NullableContextAttribute, compilation, diagnostics)
: base(AttributeDescription.NullableContextAttribute, compilation, diagnostics, includeAttributeUsageAttribute: true)
{
var byteType = compilation.GetSpecialType(SpecialType.System_Byte);
Binder.ReportUseSiteDiagnostics(byteType, diagnostics, Location.None);
@@ -44,6 +45,14 @@ internal sealed class SynthesizedEmbeddedNullableContextAttributeSymbol : Synthe

public override ImmutableArray<MethodSymbol> Constructors => _constructors;

internal override AttributeUsageInfo GetAttributeUsageInfo()
{
return new AttributeUsageInfo(
AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Struct,
allowMultiple: false,
inherited: false);
}

private void GenerateConstructorBody(SyntheticBoundNodeFactory factory, ArrayBuilder<BoundStatement> statements, ImmutableArray<ParameterSymbol> parameters)
{
statements.Add(
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
@@ -16,7 +17,7 @@ internal sealed class SynthesizedEmbeddedNullablePublicOnlyAttributeSymbol : Syn
public SynthesizedEmbeddedNullablePublicOnlyAttributeSymbol(
CSharpCompilation compilation,
DiagnosticBag diagnostics)
: base(AttributeDescription.NullablePublicOnlyAttribute, compilation, diagnostics)
: base(AttributeDescription.NullablePublicOnlyAttribute, compilation, diagnostics, includeAttributeUsageAttribute: true)
{
var boolType = compilation.GetSpecialType(SpecialType.System_Boolean);
Binder.ReportUseSiteDiagnostics(boolType, diagnostics, Location.None);
@@ -44,6 +45,11 @@ internal sealed class SynthesizedEmbeddedNullablePublicOnlyAttributeSymbol : Syn

public override ImmutableArray<MethodSymbol> Constructors => _constructors;

internal override AttributeUsageInfo GetAttributeUsageInfo()
{
return new AttributeUsageInfo(AttributeTargets.Module, allowMultiple: false, inherited: false);
}

private void GenerateConstructorBody(SyntheticBoundNodeFactory factory, ArrayBuilder<BoundStatement> statements, ImmutableArray<ParameterSymbol> parameters)
{
statements.Add(

0 comments on commit 3272de5

Please sign in to comment.
You can’t perform that action at this time.