Files
2026-08-27 10:56:38 -06:00

376 lines
16 KiB
C#

using System;
using System.Collections.Immutable;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
internal abstract class FieldSymbolWithAttributesAndModifiers : FieldSymbol, IAttributeTargetSymbol
{
private CustomAttributesBag<CSharpAttributeData> _lazyCustomAttributesBag;
protected SymbolCompletionState state;
internal abstract Location ErrorLocation { get; }
protected abstract DeclarationModifiers Modifiers { get; }
protected abstract SyntaxList<AttributeListSyntax> AttributeDeclarationSyntaxList { get; }
protected abstract IAttributeTargetSymbol AttributeOwner { get; }
IAttributeTargetSymbol IAttributeTargetSymbol.AttributesOwner => AttributeOwner;
AttributeLocation IAttributeTargetSymbol.DefaultAttributeLocation => AttributeLocation.Field;
AttributeLocation IAttributeTargetSymbol.AllowedAttributeLocations => AttributeLocation.Field;
public sealed override bool IsStatic => (Modifiers & DeclarationModifiers.Static) != 0;
public sealed override bool IsReadOnly => (Modifiers & DeclarationModifiers.ReadOnly) != 0;
public sealed override Accessibility DeclaredAccessibility => ModifierUtils.EffectiveAccessibility(Modifiers);
public sealed override bool IsConst => (Modifiers & DeclarationModifiers.Const) != 0;
public sealed override bool IsVolatile => (Modifiers & DeclarationModifiers.Volatile) != 0;
public sealed override bool IsFixedSizeBuffer => (Modifiers & DeclarationModifiers.Fixed) != 0;
internal sealed override ObsoleteAttributeData ObsoleteAttributeData
{
get
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
if (!((SourceMemberContainerTypeSymbol)ContainingType).AnyMemberHasAttributes)
{
return null;
}
CustomAttributesBag<CSharpAttributeData> lazyCustomAttributesBag = _lazyCustomAttributesBag;
if (lazyCustomAttributesBag != null && lazyCustomAttributesBag.IsEarlyDecodedWellKnownAttributeDataComputed)
{
CommonFieldEarlyWellKnownAttributeData val = (CommonFieldEarlyWellKnownAttributeData)lazyCustomAttributesBag.EarlyDecodedWellKnownAttributeData;
if (val == null)
{
return null;
}
return val.ObsoleteAttributeData;
}
return ObsoleteAttributeData.Uninitialized;
}
}
public override FlowAnalysisAnnotations FlowAnalysisAnnotations => DecodeFlowAnalysisAttributes(GetDecodedWellKnownAttributeData());
internal sealed override bool HasSpecialName
{
get
{
if (HasRuntimeSpecialName)
{
return true;
}
FieldWellKnownAttributeData decodedWellKnownAttributeData = GetDecodedWellKnownAttributeData();
if (decodedWellKnownAttributeData != null)
{
return ((CommonFieldWellKnownAttributeData)decodedWellKnownAttributeData).HasSpecialNameAttribute;
}
return false;
}
}
internal sealed override bool IsNotSerialized
{
get
{
FieldWellKnownAttributeData decodedWellKnownAttributeData = GetDecodedWellKnownAttributeData();
if (decodedWellKnownAttributeData != null)
{
return ((CommonFieldWellKnownAttributeData)decodedWellKnownAttributeData).HasNonSerializedAttribute;
}
return false;
}
}
internal sealed override MarshalPseudoCustomAttributeData MarshallingInformation
{
get
{
FieldWellKnownAttributeData decodedWellKnownAttributeData = GetDecodedWellKnownAttributeData();
if (decodedWellKnownAttributeData == null)
{
return null;
}
return ((CommonFieldWellKnownAttributeData)decodedWellKnownAttributeData).MarshallingInformation;
}
}
internal sealed override int? TypeLayoutOffset
{
get
{
FieldWellKnownAttributeData decodedWellKnownAttributeData = GetDecodedWellKnownAttributeData();
if (decodedWellKnownAttributeData == null)
{
return null;
}
return ((CommonFieldWellKnownAttributeData)decodedWellKnownAttributeData).Offset;
}
}
internal sealed override bool HasComplete(CompletionPart part)
{
return state.HasComplete(part);
}
public sealed override ImmutableArray<CSharpAttributeData> GetAttributes()
{
return GetAttributesBag().Attributes;
}
private CustomAttributesBag<CSharpAttributeData> GetAttributesBag()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
CustomAttributesBag<CSharpAttributeData> lazyCustomAttributesBag = _lazyCustomAttributesBag;
if (lazyCustomAttributesBag != null && lazyCustomAttributesBag.IsSealed)
{
return lazyCustomAttributesBag;
}
if (LoadAndValidateAttributes(OneOrMany.Create<SyntaxList<AttributeListSyntax>>(AttributeDeclarationSyntaxList), ref _lazyCustomAttributesBag))
{
state.NotePartComplete(CompletionPart.Attributes);
}
return _lazyCustomAttributesBag;
}
protected FieldWellKnownAttributeData GetDecodedWellKnownAttributeData()
{
CustomAttributesBag<CSharpAttributeData> val = _lazyCustomAttributesBag;
if (val == null || !val.IsDecodedWellKnownAttributeDataComputed)
{
val = GetAttributesBag();
}
return (FieldWellKnownAttributeData)(object)val.DecodedWellKnownAttributeData;
}
internal sealed override (CSharpAttributeData?, BoundAttribute?) EarlyDecodeWellKnownAttribute(ref EarlyDecodeWellKnownAttributeArguments<EarlyWellKnownAttributeBinder, NamedTypeSymbol, AttributeSyntax, AttributeLocation> arguments)
{
if (Symbol.EarlyDecodeDeprecatedOrExperimentalOrObsoleteAttribute(ref arguments, out CSharpAttributeData attributeData, out BoundAttribute boundAttribute, out ObsoleteAttributeData obsoleteData))
{
if (obsoleteData != null)
{
arguments.GetOrCreateData<CommonFieldEarlyWellKnownAttributeData>().ObsoleteAttributeData = obsoleteData;
}
return (attributeData, boundAttribute);
}
return base.EarlyDecodeWellKnownAttribute(ref arguments);
}
protected override void DecodeWellKnownAttributeImpl(ref DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
BindingDiagnosticBag bindingDiagnosticBag = (BindingDiagnosticBag)(object)arguments.Diagnostics;
CSharpAttributeData attribute = arguments.Attribute;
if (attribute.IsTargetAttribute(this, AttributeDescription.SpecialNameAttribute))
{
((CommonFieldWellKnownAttributeData)arguments.GetOrCreateData<FieldWellKnownAttributeData>()).HasSpecialNameAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NonSerializedAttribute))
{
((CommonFieldWellKnownAttributeData)arguments.GetOrCreateData<FieldWellKnownAttributeData>()).HasNonSerializedAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.FieldOffsetAttribute))
{
if (IsStatic || IsConst)
{
bindingDiagnosticBag.Add(ErrorCode.ERR_StructOffsetOnBadField, ((SyntaxNode)arguments.AttributeSyntaxOpt.Name).Location);
return;
}
TypedConstant val = ((AttributeData)attribute).CommonConstructorArguments[0];
int num = ((TypedConstant)(ref val)).DecodeValue<int>((SpecialType)13);
if (num < 0)
{
CSharpSyntaxNode attributeArgumentSyntax = ((AttributeData)(object)attribute).GetAttributeArgumentSyntax(0, arguments.AttributeSyntaxOpt);
bindingDiagnosticBag.Add(ErrorCode.ERR_InvalidAttributeArgument, ((SyntaxNode)attributeArgumentSyntax).Location, arguments.AttributeSyntaxOpt.GetErrorDisplayName());
num = 0;
}
((CommonFieldWellKnownAttributeData)arguments.GetOrCreateData<FieldWellKnownAttributeData>()).SetFieldOffset(num);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.MarshalAsAttribute))
{
MarshalAsAttributeDecoder<FieldWellKnownAttributeData, AttributeSyntax, CSharpAttributeData, AttributeLocation>.Decode(ref arguments, AttributeTargets.Field, (CommonMessageProvider)(object)MessageProvider.Instance);
}
else if (!ReportExplicitUseOfReservedAttributes(in arguments, ReservedAttributes.DynamicAttribute | ReservedAttributes.IsReadOnlyAttribute | ReservedAttributes.IsUnmanagedAttribute | ReservedAttributes.IsByRefLikeAttribute | ReservedAttributes.TupleElementNamesAttribute | ReservedAttributes.NullableAttribute | ReservedAttributes.NativeIntegerAttribute | ReservedAttributes.RequiredMemberAttribute | ReservedAttributes.RequiresLocationAttribute))
{
if (attribute.IsTargetAttribute(this, AttributeDescription.DateTimeConstantAttribute))
{
VerifyConstantValueMatches(((AttributeData)attribute).DecodeDateTimeConstantValue(), ref arguments);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.DecimalConstantAttribute))
{
VerifyConstantValueMatches(((AttributeData)attribute).DecodeDecimalConstantValue(), ref arguments);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.AllowNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasAllowNullAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.DisallowNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasDisallowNullAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.MaybeNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasMaybeNullAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NotNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasNotNullAttribute = true;
}
}
}
private static FlowAnalysisAnnotations DecodeFlowAnalysisAttributes(FieldWellKnownAttributeData attributeData)
{
FlowAnalysisAnnotations flowAnalysisAnnotations = FlowAnalysisAnnotations.None;
if (attributeData != null)
{
if (attributeData.HasAllowNullAttribute)
{
flowAnalysisAnnotations |= FlowAnalysisAnnotations.AllowNull;
}
if (attributeData.HasDisallowNullAttribute)
{
flowAnalysisAnnotations |= FlowAnalysisAnnotations.DisallowNull;
}
if (attributeData.HasMaybeNullAttribute)
{
flowAnalysisAnnotations |= FlowAnalysisAnnotations.MaybeNull;
}
if (attributeData.HasNotNullAttribute)
{
flowAnalysisAnnotations |= FlowAnalysisAnnotations.NotNull;
}
}
return flowAnalysisAnnotations;
}
private void VerifyConstantValueMatches(ConstantValue attrValue, ref DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
if (attrValue.IsBad)
{
return;
}
FieldWellKnownAttributeData orCreateData = arguments.GetOrCreateData<FieldWellKnownAttributeData>();
BindingDiagnosticBag bindingDiagnosticBag = (BindingDiagnosticBag)(object)arguments.Diagnostics;
ConstantValue constantValue;
if (IsConst)
{
if ((int)base.Type.SpecialType == 17)
{
constantValue = GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false);
if (constantValue != null && !constantValue.IsBad && constantValue != attrValue)
{
bindingDiagnosticBag.Add(ErrorCode.ERR_FieldHasMultipleDistinctConstantValues, ((SyntaxNode)arguments.AttributeSyntaxOpt).Location);
}
}
else
{
bindingDiagnosticBag.Add(ErrorCode.ERR_FieldHasMultipleDistinctConstantValues, ((SyntaxNode)arguments.AttributeSyntaxOpt).Location);
}
if (((CommonFieldWellKnownAttributeData)orCreateData).ConstValue == ConstantValue.Unset)
{
((CommonFieldWellKnownAttributeData)orCreateData).ConstValue = attrValue;
}
return;
}
constantValue = ((CommonFieldWellKnownAttributeData)orCreateData).ConstValue;
if (constantValue != ConstantValue.Unset)
{
if (constantValue != attrValue)
{
bindingDiagnosticBag.Add(ErrorCode.ERR_FieldHasMultipleDistinctConstantValues, ((SyntaxNode)arguments.AttributeSyntaxOpt).Location);
}
}
else
{
((CommonFieldWellKnownAttributeData)orCreateData).ConstValue = attrValue;
}
}
internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttributeData> boundAttributes, ImmutableArray<AttributeSyntax> allAttributeSyntaxNodes, BindingDiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
FieldWellKnownAttributeData fieldWellKnownAttributeData = (FieldWellKnownAttributeData)(object)decodedData;
TypeLayout layout;
if (((fieldWellKnownAttributeData != null) ? ((CommonFieldWellKnownAttributeData)fieldWellKnownAttributeData).Offset : ((int?)null)).HasValue)
{
layout = ContainingType.Layout;
if (((TypeLayout)(ref layout)).Kind != LayoutKind.Explicit)
{
int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.FieldOffsetAttribute);
diagnostics.Add(ErrorCode.ERR_StructOffsetOnBadStruct, ((SyntaxNode)allAttributeSyntaxNodes[index].Name).Location);
}
}
else if (!IsStatic && !IsConst)
{
layout = ContainingType.Layout;
if (((TypeLayout)(ref layout)).Kind == LayoutKind.Explicit)
{
diagnostics.Add(ErrorCode.ERR_MissingStructOffset, ErrorLocation, AttributeOwner);
}
}
base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData);
}
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<SynthesizedAttributeData> attributes)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
if ((int)RefKind == 3)
{
Symbol.AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this));
}
CSharpCompilation declaringCompilation = DeclaringCompilation;
TypeWithAnnotations typeWithAnnotations = base.TypeWithAnnotations;
if (typeWithAnnotations.Type.ContainsDynamic())
{
Symbol.AddSynthesizedAttribute(ref attributes, declaringCompilation.SynthesizeDynamicAttribute(typeWithAnnotations.Type, typeWithAnnotations.CustomModifiers.Length, (RefKind)0));
}
if (declaringCompilation.ShouldEmitNativeIntegerAttributes(typeWithAnnotations.Type))
{
Symbol.AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, typeWithAnnotations.Type));
}
if (typeWithAnnotations.Type.ContainsTupleNames())
{
Symbol.AddSynthesizedAttribute(ref attributes, declaringCompilation.SynthesizeTupleNamesAttribute(typeWithAnnotations.Type));
}
if (declaringCompilation.ShouldEmitNullableAttributes(this))
{
Symbol.AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, ContainingType.GetNullableContextValue(), typeWithAnnotations));
}
}
}