Просмотр исходного кода

[System.Reflection] CoreFX import for FieldInfo type. (#10370)

Part of #9660.

The changes:
- included FieldInfo type from CoreFX + related xunit tests;
- made Mono-implemented class partial; removed duplicated code;
- moved GetOptionalCustomModifiers and GetRequiredCustomModifiers methods to MonoField type;
- moved GetTypeModifiers extern method and related icall to MonoField type;
- updated ToString method in CustomAttributeTypedArgument type with CoreFX implementation;
Maxim Lipnin 7 лет назад
Родитель
Сommit
faaa9a41c6

+ 1 - 1
configure.ac

@@ -46,7 +46,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3`
 # There is no ordering of corlib versions, no old or new,
 # the runtime expects an exact match.
 #
-MONO_CORLIB_VERSION=5faf70a0-f7b5-4e03-9466-cd2629ddee9e
+MONO_CORLIB_VERSION=05275C31-312E-45F5-90EC-4C75A84EC1F8
 
 #
 # Put a quoted #define in config.h.

+ 1 - 1
external/api-snapshot

@@ -1 +1 @@
-Subproject commit d8e54d651e90aefe432d73fa6c6a1d5729419b71
+Subproject commit 5c36a1f71548467df367b29b2e83ab1f8473ddde

+ 1 - 1
external/corefx

@@ -1 +1 @@
-Subproject commit d4745d06a2b6d59725ecf82758d37ff9649953b3
+Subproject commit ba2f6954028e8dc4a571b34a23a29fbe9e8a40d2

+ 5 - 0
mcs/class/corlib/System.Reflection.Emit/FieldOnTypeBuilderInst.cs

@@ -128,6 +128,11 @@ namespace System.Reflection.Emit
 			throw new NotSupportedException ();
 		}
 
+        internal override int GetFieldOffset ()
+        {
+            throw new SystemException ("This method should not be called");
+        }
+
 		// Called from the runtime to return the corresponding finished FieldInfo object
 		internal FieldInfo RuntimeResolve () {
 			var type = instantiation.RuntimeResolve ();

+ 52 - 16
mcs/class/corlib/System.Reflection/CustomAttributeTypedArgument.cs

@@ -29,8 +29,11 @@
 
 
 using System;
-using System.Runtime.InteropServices;
+using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
 
 namespace System.Reflection {
 
@@ -47,7 +50,7 @@ namespace System.Reflection {
 				throw new ArgumentNullException ("argumentType");
 
 			this.argumentType = argumentType;
-			this.value = value;
+			this.value = (value == null) ? null : CanonicalizeValue (value);
 
 			// MS seems to convert arrays into a ReadOnlyCollection
 			if (value is Array) {
@@ -67,7 +70,7 @@ namespace System.Reflection {
 				throw new ArgumentNullException ("value");
 
 			this.argumentType = value.GetType ();
-			this.value = value;
+			this.value = CanonicalizeValue (value);
 		}
 
 		public Type ArgumentType {
@@ -82,17 +85,46 @@ namespace System.Reflection {
 			}
 		}
 
-		public override string ToString ()
+		public override string ToString () => ToString (typed: false);
+
+		internal string ToString (bool typed)
 		{
-			string val = value != null ? value.ToString () : String.Empty;
-			if (argumentType == typeof (string))
-				return "\"" + val + "\"";
-			if (argumentType == typeof (Type)) 
-				return "typeof (" + val + ")";
-			if (argumentType.IsEnum)
-				return "(" + argumentType.Name + ")" + val;
-
-			return val;
+			if (ArgumentType == null)
+				return base.ToString (); // Someone called ToString() on "default(CustomAttributeTypedArgument)"
+
+			try	{
+				if (ArgumentType.IsEnum)
+					return string.Format (CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullName);
+
+				if (Value == null)
+					return string.Format (CultureInfo.CurrentCulture, typed ? "null" : "({0})null", ArgumentType.Name);
+
+				if (ArgumentType == typeof (string))
+					return string.Format (CultureInfo.CurrentCulture, "\"{0}\"", Value);
+
+				if (ArgumentType == typeof (char))
+					return string.Format (CultureInfo.CurrentCulture, "'{0}'", Value);
+
+				if (ArgumentType == typeof (Type))
+					return string.Format (CultureInfo.CurrentCulture, "typeof({0})", ((Type)Value).FullName);
+
+				if (ArgumentType.IsArray) {
+					StringBuilder result = new StringBuilder ();
+					IList<CustomAttributeTypedArgument> array = Value as IList<CustomAttributeTypedArgument>;
+
+					Type elementType = ArgumentType.GetElementType ();
+					result.AppendFormat (CultureInfo.CurrentCulture, @"new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullName : elementType.Name, array.Count);
+
+					for (int i = 0; i < array.Count; i++)
+						result.AppendFormat (CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", array [i].ToString (elementType != typeof (object)));
+
+					return result.Append (" }").ToString ();
+				}
+
+				return string.Format (CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.Name);
+			} catch (MissingMetadataException) {
+				return base.ToString (); // Failsafe. Code inside "try" should still strive to avoid trigging a MissingMetadataException as caught exceptions are annoying when debugging.
+			}
 		}
 
 		public override bool Equals (object obj)
@@ -118,8 +150,12 @@ namespace System.Reflection {
 		{
 			return !left.Equals (right);
 		}
-	}
 
+		private static object CanonicalizeValue (object value)
+		{
+			if (value is Enum e) 
+				return e.GetValue ();
+			return value;
+		}		
+	}
 }
-
-

+ 2 - 228
mcs/class/corlib/System.Reflection/FieldInfo.cs

@@ -35,113 +35,8 @@ using System.Runtime.InteropServices;
 
 namespace System.Reflection {
 
-	[ComVisible (true)]
-	[ComDefaultInterfaceAttribute (typeof (_FieldInfo))]
 	[Serializable]
-	[ClassInterface(ClassInterfaceType.None)]
-#if MOBILE
-	public abstract class FieldInfo : MemberInfo {
-#else
-	public abstract class FieldInfo : MemberInfo, _FieldInfo {
-#endif
-		public abstract FieldAttributes Attributes {get;}
-		public abstract RuntimeFieldHandle FieldHandle {get;}
-
-		protected FieldInfo () {}
-		
-		public abstract Type FieldType { get; }
-
-		public abstract object GetValue(object obj);
-
-		public override MemberTypes MemberType {
-			get { return MemberTypes.Field;}
-		}
-
-		public bool IsLiteral
-		{
-			get {return (Attributes & FieldAttributes.Literal) != 0;}
-		} 
-
-		public bool IsStatic
-		{
-			get {return (Attributes & FieldAttributes.Static) != 0;}
-		} 
-
-		public bool IsInitOnly
-		{
-			get {return (Attributes & FieldAttributes.InitOnly) != 0;}
-		} 
-		public Boolean IsPublic
-		{ 
-			get
-			{
-				return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
-			}
-		}
-		public Boolean IsPrivate
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private;
-			}
-		}
-		public Boolean IsFamily
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family;
-			}
-		}
-		public Boolean IsAssembly
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly;
-			}
-		}
-		public Boolean IsFamilyAndAssembly
-		{
-			get {
-				return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem;
-			}
-		}
-		public Boolean IsFamilyOrAssembly
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem;
-			}
-		}
-		public Boolean IsPinvokeImpl
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.PinvokeImpl) == FieldAttributes.PinvokeImpl;
-			}
-		}
-		public Boolean IsSpecialName
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.SpecialName) == FieldAttributes.SpecialName;
-			}
-		}
-		public Boolean IsNotSerialized
-		{
-			get
-			{
-				return (Attributes & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
-			}
-		}
-
-		public abstract void SetValue (object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture);
-
-		[DebuggerHidden]
-		[DebuggerStepThrough]
-		public void SetValue (object obj, object value)
-		{
-			SetValue (obj, value, 0, null, null);
-		}
+	partial class FieldInfo : MemberInfo {
 
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
 		private static extern FieldInfo internal_from_handle_type (IntPtr field_handle, IntPtr type_handle);
@@ -164,32 +59,7 @@ namespace System.Reflection {
 			return fi;
 		}
 
-		//
-		// Note: making this abstract imposes an implementation requirement
-		//       on any class that derives from it.  However, since it's also
-		//       internal, that means only classes inside corlib can derive
-		//       from FieldInfo.  See
-		//
-		//          errors/cs0534-4.cs errors/CS0534-4-lib.cs
-		//
-		//          class/Microsoft.JScript/Microsoft.JScript/JSFieldInfo.cs
-		//
-		internal virtual int GetFieldOffset ()
-		{
-			throw new SystemException ("This method should not be called");
-		}
-
-		[CLSCompliant(false)]
-		public virtual object GetValueDirect (TypedReference obj)
-		{
-			throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS"));
-		}
-
-		[CLSCompliant(false)]
-		public virtual void SetValueDirect (TypedReference obj, object value)
-		{
-			throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS"));
-		}
+		internal abstract int GetFieldOffset ();
 
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
 		private extern MarshalAsAttribute get_marshal_info ();
@@ -263,101 +133,5 @@ namespace System.Reflection {
 			return attrsData;
 		}
 
-		[MethodImplAttribute (MethodImplOptions.InternalCall)]
-		extern Type[] GetTypeModifiers (bool optional);
-
-		public virtual Type[] GetOptionalCustomModifiers () {
-			Type[] types = GetTypeModifiers (true);
-			if (types == null)
-				return Type.EmptyTypes;
-			return types;
-		}
-
-		public virtual Type[] GetRequiredCustomModifiers () {
-			Type[] types = GetTypeModifiers (false);
-			if (types == null)
-				return Type.EmptyTypes;
-			return types;
-		}
-
-		public virtual object GetRawConstantValue ()
-		{
-			throw new NotSupportedException ("This non-CLS method is not implemented.");
-		}
-
-
-		public override bool Equals (object obj)
-		{
-			return obj == (object) this;
-		}
-
-		public override int GetHashCode ()
-		{
-			return base.GetHashCode ();
-		}
-
-		public static bool operator == (FieldInfo left, FieldInfo right)
-		{
-			if ((object)left == (object)right)
-				return true;
-			if ((object)left == null ^ (object)right == null)
-				return false;
-			return left.Equals (right);
-		}
-
-		public static bool operator != (FieldInfo left, FieldInfo right)
-		{
-			if ((object)left == (object)right)
-				return false;
-			if ((object)left == null ^ (object)right == null)
-				return true;
-			return !left.Equals (right);
-		}
-		
-		public virtual bool IsSecurityCritical {
-			get {
-				throw new NotSupportedException ();
-			}
-		}
-		
-		public virtual bool IsSecuritySafeCritical {
-			get {
-				throw new NotSupportedException ();
-			}
-		}
-
-		public virtual bool IsSecurityTransparent {
-			get {
-				throw new NotSupportedException ();
-			}
-		}
-
-#if !MOBILE
-		void _FieldInfo.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
-		{
-			throw new NotImplementedException ();
-		}
-
-		Type _FieldInfo.GetType ()
-		{
-			// Required or object::GetType becomes virtual final
-			return base.GetType ();
-		}
-
-		void _FieldInfo.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
-		{
-			throw new NotImplementedException ();
-		}
-
-		void _FieldInfo.GetTypeInfoCount (out uint pcTInfo)
-		{
-			throw new NotImplementedException ();
-		}
-
-		void _FieldInfo.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
-		{
-			throw new NotImplementedException ();
-		}
-#endif
 	}
 }

+ 9 - 0
mcs/class/corlib/System.Reflection/MonoField.cs

@@ -329,5 +329,14 @@ namespace System.Reflection {
 		
 		[MethodImplAttribute (MethodImplOptions.InternalCall)]
 		internal static extern int get_metadata_token (MonoField monoField);
+
+		[MethodImplAttribute (MethodImplOptions.InternalCall)]
+		extern Type[] GetTypeModifiers (bool optional);
+
+		public override Type[] GetOptionalCustomModifiers () => GetCustomModifiers (true);
+
+		public override Type[] GetRequiredCustomModifiers () => GetCustomModifiers (false);
+
+		private Type[] GetCustomModifiers (bool optional) => GetTypeModifiers (optional) ?? Type.EmptyTypes;
 	}
 }

+ 3 - 3
mcs/class/corlib/Test/System.Reflection/CustomAttributeDataTest.cs

@@ -98,7 +98,7 @@ namespace MonoTests.System.Reflection
 
 			Assert.AreEqual (typeof (MarshalAsAttribute), marshalAsAttributeData.AttributeType);
 			Assert.AreEqual (typeof (UnmanagedType), marshalAsAttributeCtorArg.ArgumentType);
-			Assert.AreEqual (UnmanagedType.LPStr, marshalAsAttributeCtorArg.Value);
+			Assert.AreEqual ((int)UnmanagedType.LPStr, marshalAsAttributeCtorArg.Value);
 		}
 
 		[Test]
@@ -116,7 +116,7 @@ namespace MonoTests.System.Reflection
 			Assert.AreEqual (typeof (NonSerializedAttribute), nonSerializedAttributeData.AttributeType);
 			Assert.AreEqual (typeof (MarshalAsAttribute), marshalAsAttributeData.AttributeType);
 			Assert.AreEqual (typeof (UnmanagedType), marshalAsAttributeDataCtorArg.ArgumentType);
-			Assert.AreEqual (UnmanagedType.LPStr, marshalAsAttributeDataCtorArg.Value);
+			Assert.AreEqual ((int)UnmanagedType.LPStr, marshalAsAttributeDataCtorArg.Value);
 		}
 
 		[Test]
@@ -131,7 +131,7 @@ namespace MonoTests.System.Reflection
 			Assert.AreEqual (1, customAttributesData.Count);
 			Assert.AreEqual (typeof (MarshalAsAttribute), marshalAsAttributeData.AttributeType);
 			Assert.AreEqual (typeof (UnmanagedType), ctorArg.ArgumentType);
-			Assert.AreEqual (UnmanagedType.LPStr, ctorArg.Value);
+			Assert.AreEqual ((int)UnmanagedType.LPStr, ctorArg.Value);
 		}
 	}
 }

+ 2 - 0
mcs/class/corlib/corlib.csproj

@@ -395,6 +395,7 @@
     <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\EventAttributes.cs" />
     <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\ExceptionHandlingClauseOptions.cs" />
     <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\FieldAttributes.cs" />
+    <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\FieldInfo.cs" />
     <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\GenericParameterAttributes.cs" />
     <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\ICustomAttributeProvider.cs" />
     <Compile Include="..\..\..\external\corefx\src\Common\src\CoreLib\System\Reflection\IReflect.cs" />
@@ -704,6 +705,7 @@
     <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\MissingMemberException.cs" />
     <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\Number.CoreRT.cs" />
     <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\OutOfMemoryException.cs" />
+    <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\Reflection\MissingMetadataException.cs" />
     <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\Runtime\CompilerServices\ReflectionBlockedAttribute.cs" />
     <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\Runtime\CompilerServices\TaskAwaiter.cs" />
     <Compile Include="..\..\..\external\corert\src\System.Private.CoreLib\src\System\Threading\CancellationTokenRegistration.cs" />

+ 2 - 0
mcs/class/corlib/corlib.dll.sources

@@ -230,6 +230,8 @@ System.Reflection/CustomAttributeTypedArgument.cs
 System.Reflection/EventInfo.cs
 System.Reflection/ExceptionHandlingClause.cs
 System.Reflection/FieldInfo.cs
+../../../external/corefx/src/Common/src/CoreLib/System/Reflection/FieldInfo.cs
+../../../external/corert/src/System.Private.CoreLib/src/System/Reflection/MissingMetadataException.cs
 ../../../external/corefx/src/Common/src/CoreLib/System/Reflection/ImageFileMachine.cs
 System.Reflection/LocalVariableInfo.cs
 System.Reflection/MethodBody.cs

+ 2 - 0
mcs/class/corlib/corlib_xtest.dll.sources

@@ -14,7 +14,9 @@
 
 ../../../external/corefx/src/System.Reflection.Emit/tests/Utilities.cs
 
+../../../external/corefx/src/System.Reflection/tests/Common.cs
 ../../../external/corefx/src/System.Reflection/tests/ConstructorInfoTests.cs
+../../../external/corefx/src/System.Reflection/tests/FieldInfoTests.cs
 ../../../external/corefx/src/System.Reflection/tests/ManifestResourceInfoTests.cs
 #../../../external/corefx/src/System.Reflection/tests/MemberInfoTests.cs
 

+ 5 - 0
mcs/class/referencesource/mscorlib/system/runtime/serialization/serializationfieldinfo.cs

@@ -88,6 +88,11 @@ namespace System.Runtime.Serialization {
                 return m_field.FieldType;
             }
         }
+
+        internal override int GetFieldOffset ()
+        {
+            throw new SystemException ("This method should not be called");
+        }
         
         public override Object GetValue(Object obj) {
             return m_field.GetValue(obj);

+ 3 - 3
mono/metadata/icall-def.h

@@ -588,9 +588,8 @@ ICALL_TYPE(EVENTI, "System.Reflection.EventInfo", EVENTI_1)
 HANDLES(ICALL(EVENTI_1, "internal_from_handle_type", ves_icall_System_Reflection_EventInfo_internal_from_handle_type))
 
 ICALL_TYPE(FIELDI, "System.Reflection.FieldInfo", FILEDI_1)
-HANDLES(ICALL(FILEDI_1, "GetTypeModifiers", ves_icall_System_Reflection_FieldInfo_GetTypeModifiers))
-HANDLES(ICALL(FILEDI_2, "get_marshal_info", ves_icall_System_Reflection_FieldInfo_get_marshal_info))
-HANDLES(ICALL(FILEDI_3, "internal_from_handle_type", ves_icall_System_Reflection_FieldInfo_internal_from_handle_type))
+HANDLES(ICALL(FILEDI_1, "get_marshal_info", ves_icall_System_Reflection_FieldInfo_get_marshal_info))
+HANDLES(ICALL(FILEDI_2, "internal_from_handle_type", ves_icall_System_Reflection_FieldInfo_internal_from_handle_type))
 
 ICALL_TYPE(MBASE, "System.Reflection.MethodBase", MBASE_1)
 HANDLES(ICALL(MBASE_1, "GetCurrentMethod", ves_icall_GetCurrentMethod))
@@ -629,6 +628,7 @@ ICALL_TYPE(MFIELD, "System.Reflection.MonoField", MFIELD_1)
 HANDLES(ICALL(MFIELD_1, "GetFieldOffset", ves_icall_MonoField_GetFieldOffset))
 HANDLES(ICALL(MFIELD_2, "GetParentType", ves_icall_MonoField_GetParentType))
 ICALL(MFIELD_5, "GetRawConstantValue", ves_icall_MonoField_GetRawConstantValue)
+HANDLES(ICALL(MFIELD_9, "GetTypeModifiers", ves_icall_System_Reflection_FieldInfo_GetTypeModifiers))
 ICALL(MFIELD_3, "GetValueInternal", ves_icall_MonoField_GetValueInternal)
 HANDLES(ICALL(MFIELD_6, "ResolveType", ves_icall_MonoField_ResolveType))
 HANDLES(ICALL(MFIELD_4, "SetValueInternal", ves_icall_MonoField_SetValueInternal))