File: System\Reflection\Runtime\FieldInfos\NativeFormat\NativeFormatRuntimeFieldInfo.cs
Web Access
Project: src\src\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj (System.Private.CoreLib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Reflection.Runtime.BindingFlagSupport;
using System.Reflection.Runtime.CustomAttributes;
using System.Reflection.Runtime.FieldInfos;
using System.Reflection.Runtime.General;
using System.Reflection.Runtime.General.NativeFormat;
using System.Reflection.Runtime.TypeInfos;
using System.Reflection.Runtime.TypeInfos.NativeFormat;
using System.Runtime.CompilerServices;

using Internal.Metadata.NativeFormat;
using Internal.Reflection.Core;
using Internal.Reflection.Core.Execution;
using Internal.Runtime.Augments;

namespace System.Reflection.Runtime.FieldInfos.NativeFormat
{
    //
    // The Runtime's implementation of fields.
    //
    [DebuggerDisplay("{_debugName}")]
    internal sealed partial class NativeFormatRuntimeFieldInfo : RuntimeFieldInfo
    {
        //
        // fieldHandle    - the "tkFieldDef" that identifies the field.
        // definingType   - the "tkTypeDef" that defined the field (this is where you get the metadata reader that created fieldHandle.)
        // contextType    - the type that supplies the type context (i.e. substitutions for generic parameters.) Though you
        //                  get your raw information from "definingType", you report "contextType" as your DeclaringType property.
        //
        //  For example:
        //
        //       typeof(Foo<>).GetTypeInfo().DeclaredMembers
        //
        //           The definingType and contextType are both Foo<>
        //
        //       typeof(Foo<int,String>).GetTypeInfo().DeclaredMembers
        //
        //          The definingType is "Foo<,>"
        //          The contextType is "Foo<int,String>"
        //
        //  We don't report any DeclaredMembers for arrays or generic parameters so those don't apply.
        //
        private NativeFormatRuntimeFieldInfo(FieldHandle fieldHandle, NativeFormatRuntimeNamedTypeInfo definingTypeInfo, RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) :
            base(contextTypeInfo, reflectedType)
        {
            _fieldHandle = fieldHandle;
            _definingTypeInfo = definingTypeInfo;
            _reader = definingTypeInfo.Reader;
            _field = fieldHandle.GetField(_reader);
        }

        public sealed override FieldAttributes Attributes
        {
            get
            {
                return _field.Flags;
            }
        }

        public sealed override Type[] GetOptionalCustomModifiers() => FieldTypeHandle.GetCustomModifiers(_reader, _contextTypeInfo.TypeContext, optional: true);

        public sealed override Type[] GetRequiredCustomModifiers() => FieldTypeHandle.GetCustomModifiers(_reader, _contextTypeInfo.TypeContext, optional: false);

        public sealed override int MetadataToken
        {
            get
            {
                throw new InvalidOperationException(SR.NoMetadataTokenAvailable);
            }
        }

        protected sealed override string MetadataName
        {
            get
            {
                return _field.Name.GetString(_reader);
            }
        }

        public sealed override string ToString()
        {
            return FieldRuntimeType.ToType().FormatTypeName() + " " + this.Name;
        }

        public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
        {
            ArgumentNullException.ThrowIfNull(other);

            if (!(other is NativeFormatRuntimeFieldInfo otherField))
                return false;
            if (!(_reader == otherField._reader))
                return false;
            if (!(_fieldHandle.Equals(otherField._fieldHandle)))
                return false;
            if (!(_definingTypeInfo.Equals(otherField._definingTypeInfo)))
                return false;
            return true;
        }

        public sealed override bool Equals(object obj)
        {
            if (!(obj is NativeFormatRuntimeFieldInfo other))
                return false;
            if (!(_reader == other._reader))
                return false;
            if (!(_fieldHandle.Equals(other._fieldHandle)))
                return false;
            if (!(_contextTypeInfo.Equals(other._contextTypeInfo)))
                return false;
            if (!(_reflectedType.Equals(other._reflectedType)))
                return false;
            return true;
        }

        public sealed override int GetHashCode()
        {
            return HashCode.Combine(_fieldHandle, _contextTypeInfo, _reflectedType);
        }

        public sealed override RuntimeFieldHandle FieldHandle
        {
            get
            {
                return RuntimeAugments.TypeLoaderCallbacks.GetRuntimeFieldHandleForComponents(
                    DeclaringType.TypeHandle,
                    _fieldHandle);
            }
        }

        protected sealed override bool GetDefaultValueIfAvailable(bool raw, out object? defaultValue)
        {
            return DefaultValueParser.GetDefaultValueFromConstantIfAny(_reader, _field.DefaultValue, FieldType, raw, out defaultValue);
        }

        protected sealed override FieldAccessor TryGetFieldAccessor()
        {
            return ReflectionCoreExecution.ExecutionEnvironment.TryGetFieldAccessor(this._reader, this.DeclaringType.TypeHandle, this.FieldType.TypeHandle, _fieldHandle);
        }

        protected sealed override RuntimeTypeInfo FieldRuntimeType
        {
            get
            {
                TypeContext typeContext = _contextTypeInfo.TypeContext;
                return FieldTypeHandle.Resolve(_reader, typeContext);
            }
        }

        protected sealed override RuntimeTypeInfo DefiningType { get { return _definingTypeInfo; } }

        protected sealed override IEnumerable<CustomAttributeData> TrueCustomAttributes => RuntimeCustomAttributeData.GetCustomAttributes(_reader, _field.CustomAttributes);

        protected sealed override int ExplicitLayoutFieldOffsetData => (int)(_field.Offset);

        public sealed override Type GetModifiedFieldType() => ModifiedType.Create(FieldRuntimeType.ToType(), _reader, FieldTypeHandle);

        private Handle FieldTypeHandle => _field.Signature.GetFieldSignature(_reader).Type;

        private readonly NativeFormatRuntimeNamedTypeInfo _definingTypeInfo;
        private readonly FieldHandle _fieldHandle;

        private readonly MetadataReader _reader;
        private readonly Field _field;
    }
}