diff options
author | Atsushi Kanamori <AtsushiKan@users.noreply.github.com> | 2017-03-20 08:18:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-20 08:18:45 -0700 |
commit | 7c77fffac0ea7399a2f7dbf217b5ea804c0c1ad0 (patch) | |
tree | 0159731fca3c52bff624641b5ab45b6ea92075af | |
parent | a54f3dfe63eaf3a813541fc3387f683d84099d93 (diff) | |
download | coreclr-7c77fffac0ea7399a2f7dbf217b5ea804c0c1ad0.tar.gz coreclr-7c77fffac0ea7399a2f7dbf217b5ea804c0c1ad0.tar.bz2 coreclr-7c77fffac0ea7399a2f7dbf217b5ea804c0c1ad0.zip |
Reconciles Type.cs with CoreRT version for move to shared partition. (#10306)
* Clone files and add resource strings.
* Subset each partial class.
* String=>string and Environment.GetResourceString => SR.cs
Doing this upfront with reduce the upcoming diffs - hopefully.
* Add IsRuntimeImplemented() emulator.
* One method was put in the wrong file. Correcting.
* Converted Type.Enum.cs to CoreRT style member by member.
* Converted Type.Helpers.cs to CoreRT style member by member.
* Internalize __Filter.cs into Type.Helpers.cs
* Pretransform to reduce diffs.
Removed contracts and comments,
"abstract public" -> "public abstract"
* Converted Type.cs to CoreRT style member by member.
* Eh.. rather not share IsInterface and IsSerializable than have that #if CORECLR.
* Transplant the CoreRt files (now just a reordering.)
-rw-r--r-- | src/mscorlib/System.Private.CoreLib.csproj | 4 | ||||
-rw-r--r-- | src/mscorlib/src/SR.cs | 24 | ||||
-rw-r--r-- | src/mscorlib/src/System.Private.CoreLib.txt | 4 | ||||
-rw-r--r-- | src/mscorlib/src/System/Type.CoreCLR.cs | 253 | ||||
-rw-r--r-- | src/mscorlib/src/System/Type.Enum.cs | 186 | ||||
-rw-r--r-- | src/mscorlib/src/System/Type.Helpers.cs | 499 | ||||
-rw-r--r-- | src/mscorlib/src/System/Type.cs | 1921 | ||||
-rw-r--r-- | src/mscorlib/src/System/__Filters.cs | 163 |
8 files changed, 1165 insertions, 1889 deletions
diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj index be0b4104e0..6673ee8d3b 100644 --- a/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -330,7 +330,6 @@ <Compile Include="$(BclSourcesRoot)\System\OutOfMemoryException.cs" /> <Compile Include="$(BclSourcesRoot)\System\Delegate.cs" /> <Compile Include="$(BclSourcesRoot)\System\MulticastDelegate.cs" /> - <Compile Include="$(BclSourcesRoot)\System\__Filters.cs" /> <Compile Include="$(BclSourcesRoot)\System\__HResults.cs" /> <Compile Include="$(BclSourcesRoot)\System\BCLDebug.cs" /> <Compile Include="$(BclSourcesRoot)\System\Activator.cs" /> @@ -401,6 +400,9 @@ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.StringSerializer.cs" /> <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.TransitionTime.cs" /> <Compile Include="$(BclSourcesRoot)\System\Type.cs" /> + <Compile Include="$(BclSourcesRoot)\System\Type.CoreCLR.cs" /> + <Compile Include="$(BclSourcesRoot)\System\Type.Enum.cs" /> + <Compile Include="$(BclSourcesRoot)\System\Type.Helpers.cs" /> <Compile Include="$(BclSourcesRoot)\System\TypeNameParser.cs" /> <Compile Include="$(BclSourcesRoot)\System\TypedReference.cs" /> <Compile Include="$(BclSourcesRoot)\System\TypeLoadException.cs" /> diff --git a/src/mscorlib/src/SR.cs b/src/mscorlib/src/SR.cs index 7ef57ec058..963009c23e 100644 --- a/src/mscorlib/src/SR.cs +++ b/src/mscorlib/src/SR.cs @@ -990,4 +990,28 @@ internal static class SR internal static string PlatformNotSupported_ReflectionOnly => Environment.GetResourceString("PlatformNotSupported_ReflectionOnly"); + + internal static string Arg_EnumAndObjectMustBeSameType => + Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType"); + + internal static string Arg_EnumUnderlyingTypeAndObjectMustBeSameType => + Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType"); + + internal static string Arg_MustBeEnum => + Environment.GetResourceString("Arg_MustBeEnum"); + + internal static string Arg_MustBeEnumBaseTypeOrEnum => + Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"); + + internal static string Arg_NotGenericParameter => + Environment.GetResourceString("Arg_NotGenericParameter"); + + internal static string Argument_InvalidEnum => + Environment.GetResourceString("Argument_InvalidEnum"); + + internal static string InvalidFilterCriteriaException_CritInt => + Environment.GetResourceString("InvalidFilterCriteriaException_CritInt"); + + internal static string InvalidOperation_UnknownEnumType => + Environment.GetResourceString("InvalidOperation_UnknownEnumType"); } diff --git a/src/mscorlib/src/System.Private.CoreLib.txt b/src/mscorlib/src/System.Private.CoreLib.txt index d2714bb546..0197305a75 100644 --- a/src/mscorlib/src/System.Private.CoreLib.txt +++ b/src/mscorlib/src/System.Private.CoreLib.txt @@ -1427,8 +1427,8 @@ RFLCT.InvalidPropFail = '{0}' property specified was not found. RFLCT.InvalidFieldFail = '{0}' field specified was not found. ;InvalidFilterCriteriaException -RFLCT.FltCritString = A String must be provided for the filter criteria. -RFLCT.FltCritInt = An Int32 must be provided for the filter criteria. +InvalidFilterCriteriaException_CritString = A String must be provided for the filter criteria. +InvalidFilterCriteriaException_CritInt = An Int32 must be provided for the filter criteria. ; TargetException RFLCT.Targ_ITargMismatch = Object does not match target type. diff --git a/src/mscorlib/src/System/Type.CoreCLR.cs b/src/mscorlib/src/System/Type.CoreCLR.cs new file mode 100644 index 0000000000..1a8a36f098 --- /dev/null +++ b/src/mscorlib/src/System/Type.CoreCLR.cs @@ -0,0 +1,253 @@ +// 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. + +// +// +// +// Implements System.Type +// +// ====================================================================================== + +using System.Reflection; +using System.Threading; +using System.Runtime.CompilerServices; +using System.Diagnostics.Contracts; +using StackCrawlMark = System.Threading.StackCrawlMark; + +namespace System +{ + public abstract partial class Type : MemberInfo, IReflect + { + // The Default binder. We create a single one and expose that. + private static Binder defaultBinder; + + public bool IsInterface + { + get + { + RuntimeType rt = this as RuntimeType; + if (rt != null) + return RuntimeTypeHandle.IsInterface(rt); + return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface); + } + } + + public virtual bool IsSerializable + { + get + { + if ((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0) + return true; + + RuntimeType rt = this.UnderlyingSystemType as RuntimeType; + if (rt != null) + return rt.IsSpecialSerializableType(); + + return false; + } + } + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public static Type GetType(String typeName, bool throwOnError, bool ignoreCase) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeType.GetType(typeName, throwOnError, ignoreCase, false, ref stackMark); + } + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public static Type GetType(String typeName, bool throwOnError) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeType.GetType(typeName, throwOnError, false, false, ref stackMark); + } + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public static Type GetType(String typeName) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeType.GetType(typeName, false, false, false, ref stackMark); + } + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public static Type GetType( + string typeName, + Func<AssemblyName, Assembly> assemblyResolver, + Func<Assembly, string, bool, Type> typeResolver) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark); + } + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public static Type GetType( + string typeName, + Func<AssemblyName, Assembly> assemblyResolver, + Func<Assembly, string, bool, Type> typeResolver, + bool throwOnError) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark); + } + + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod + public static Type GetType( + string typeName, + Func<AssemblyName, Assembly> assemblyResolver, + Func<Assembly, string, bool, Type> typeResolver, + bool throwOnError, + bool ignoreCase) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); + } + + //////////////////////////////////////////////////////////////////////////////// + // This will return a class based upon the progID. This is provided for + // COM classic support. Program ID's are not used in COM+ because they + // have been superceded by namespace. (This routine is called this instead + // of getClass() because of the name conflict with the first method above.) + // + // param progID: the progID of the class to retrieve + // returns: the class object associated to the progID + //// + public static Type GetTypeFromProgID(String progID, String server, bool throwOnError) + { + return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError); + } + + //////////////////////////////////////////////////////////////////////////////// + // This will return a class based upon the CLSID. This is provided for + // COM classic support. + // + // param CLSID: the CLSID of the class to retrieve + // returns: the class object associated to the CLSID + //// + public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError) + { + return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError); + } + + // Return the Default binder used by the system. + static public Binder DefaultBinder + { + get + { + // Allocate the default binder if it hasn't been allocated yet. + if (defaultBinder == null) + CreateBinder(); + return defaultBinder; + } + } + + static private void CreateBinder() + { + if (defaultBinder == null) + { + DefaultBinder binder = new DefaultBinder(); + Interlocked.CompareExchange<Binder>(ref defaultBinder, binder, null); + } + } + + internal virtual RuntimeTypeHandle GetTypeHandleInternal() + { + return TypeHandle; + } + + // Given a class handle, this will return the class for that handle. + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle); + + [Pure] + [MethodImpl(MethodImplOptions.InternalCall)] + public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle); + + + + +#if FEATURE_COMINTEROP + internal bool IsWindowsRuntimeObject + { + [Pure] + get { return IsWindowsRuntimeObjectImpl(); } + } + + internal bool IsExportedToWindowsRuntime + { + [Pure] + get { return IsExportedToWindowsRuntimeImpl(); } + } + + + // Protected routine to determine if this class represents a Windows Runtime object + virtual internal bool IsWindowsRuntimeObjectImpl() + { + throw new NotImplementedException(); + } + + // Determines if this type is exported to WinRT (i.e. is an activatable class in a managed .winmd) + virtual internal bool IsExportedToWindowsRuntimeImpl() + { + throw new NotImplementedException(); + } +#endif // FEATURE_COMINTEROP + + internal bool NeedsReflectionSecurityCheck + { + get + { + if (!IsVisible) + { + // Types which are not externally visible require security checks + return true; + } + else if (IsSecurityCritical && !IsSecuritySafeCritical) + { + // Critical types require security checks + return true; + } + else if (IsGenericType) + { + // If any of the generic arguments to this type require a security check, then this type + // also requires one. + foreach (Type genericArgument in GetGenericArguments()) + { + if (genericArgument.NeedsReflectionSecurityCheck) + { + return true; + } + } + } + else if (IsArray || IsPointer) + { + return GetElementType().NeedsReflectionSecurityCheck; + } + + return false; + } + } + + // This is only ever called on RuntimeType objects. + internal string FormatTypeName() + { + return FormatTypeName(false); + } + + internal virtual string FormatTypeName(bool serialization) + { + throw new NotImplementedException(); + } + + [Pure] + [MethodImplAttribute(MethodImplOptions.InternalCall)] + public static extern bool operator ==(Type left, Type right); + + [Pure] + [MethodImplAttribute(MethodImplOptions.InternalCall)] + public static extern bool operator !=(Type left, Type right); + + // Exists to faciliate code sharing between CoreCLR and CoreRT. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal bool IsRuntimeImplemented() => this is RuntimeType; + } +} diff --git a/src/mscorlib/src/System/Type.Enum.cs b/src/mscorlib/src/System/Type.Enum.cs new file mode 100644 index 0000000000..4d82410383 --- /dev/null +++ b/src/mscorlib/src/System/Type.Enum.cs @@ -0,0 +1,186 @@ +// 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. + +using System.Reflection; +using System.Collections; +using System.Collections.Generic; + +namespace System +{ + // + // This file collects a set of Enum-related apis that run when the Type is subclassed by an application. + // None of it runs on normal Type objects supplied by the runtime (as those types override these methods.) + // + // Since app-subclassed Types are "untrusted classes" that may or may not implement the complete surface area correctly, + // this code should be considered brittle and not changed lightly. + // + public abstract partial class Type + { + public virtual bool IsEnumDefined(object value) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + + if (!IsEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + + // Check if both of them are of the same type + Type valueType = value.GetType(); + + // If the value is an Enum then we need to extract the underlying value from it + if (valueType.IsEnum) + { + if (!valueType.IsEquivalentTo(this)) + throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), this.ToString())); + + valueType = valueType.GetEnumUnderlyingType(); + } + + // If a string is passed in + if (valueType == typeof(string)) + { + string[] names = GetEnumNames(); + if (Array.IndexOf(names, value) >= 0) + return true; + else + return false; + } + + // If an enum or integer value is passed in + if (Type.IsIntegerType(valueType)) + { + Type underlyingType = GetEnumUnderlyingType(); + // We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be. + if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl()) + throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString())); + + Array values = GetEnumRawConstantValues(); + return (BinarySearch(values, value) >= 0); + } + else + { + throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType); + } + } + + public virtual string GetEnumName(object value) + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + + if (!IsEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + + Type valueType = value.GetType(); + + if (!(valueType.IsEnum || Type.IsIntegerType(valueType))) + throw new ArgumentException(SR.Arg_MustBeEnumBaseTypeOrEnum, nameof(value)); + + Array values = GetEnumRawConstantValues(); + int index = BinarySearch(values, value); + + if (index >= 0) + { + string[] names = GetEnumNames(); + return names[index]; + } + + return null; + } + + public virtual string[] GetEnumNames() + { + if (!IsEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + + string[] names; + Array values; + GetEnumData(out names, out values); + return names; + } + + + // Returns the enum values as an object array. + private Array GetEnumRawConstantValues() + { + string[] names; + Array values; + GetEnumData(out names, out values); + return values; + } + + // This will return enumValues and enumNames sorted by the values. + private void GetEnumData(out string[] enumNames, out Array enumValues) + { + FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + + object[] values = new object[flds.Length]; + string[] names = new string[flds.Length]; + + for (int i = 0; i < flds.Length; i++) + { + names[i] = flds[i].Name; + values[i] = flds[i].GetRawConstantValue(); + } + + // Insertion Sort these values in ascending order. + // We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and + // the common case performance will be faster than quick sorting this. + IComparer comparer = Comparer<object>.Default; + for (int i = 1; i < values.Length; i++) + { + int j = i; + string tempStr = names[i]; + object val = values[i]; + bool exchanged = false; + + // Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop. + while (comparer.Compare(values[j - 1], val) > 0) + { + names[j] = names[j - 1]; + values[j] = values[j - 1]; + j--; + exchanged = true; + if (j == 0) + break; + } + + if (exchanged) + { + names[j] = tempStr; + values[j] = val; + } + } + + enumNames = names; + enumValues = values; + } + + // Convert everything to ulong then perform a binary search. + private static int BinarySearch(Array array, object value) + { + ulong[] ulArray = new ulong[array.Length]; + for (int i = 0; i < array.Length; ++i) + ulArray[i] = Enum.ToUInt64(array.GetValue(i)); + + ulong ulValue = Enum.ToUInt64(value); + + return Array.BinarySearch(ulArray, ulValue); + } + + internal static bool IsIntegerType(Type t) + { + return (t == typeof(int) || + t == typeof(short) || + t == typeof(ushort) || + t == typeof(byte) || + t == typeof(sbyte) || + t == typeof(uint) || + t == typeof(long) || + t == typeof(ulong) || + t == typeof(char) || + t == typeof(bool)); + } + } +} diff --git a/src/mscorlib/src/System/Type.Helpers.cs b/src/mscorlib/src/System/Type.Helpers.cs new file mode 100644 index 0000000000..f2f3bf601e --- /dev/null +++ b/src/mscorlib/src/System/Type.Helpers.cs @@ -0,0 +1,499 @@ +// 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. + +using System.Reflection; + +namespace System +{ + // This file collects the longer methods of Type to make the main Type class more readable. + public abstract partial class Type : MemberInfo, IReflect + { + public virtual bool ContainsGenericParameters + { + get + { + if (HasElementType) + return GetRootElementType().ContainsGenericParameters; + + if (IsGenericParameter) + return true; + + if (!IsGenericType) + return false; + + Type[] genericArguments = GetGenericArguments(); + for (int i = 0; i < genericArguments.Length; i++) + { + if (genericArguments[i].ContainsGenericParameters) + return true; + } + + return false; + } + } + + internal Type GetRootElementType() + { + Type rootElementType = this; + + while (rootElementType.HasElementType) + rootElementType = rootElementType.GetElementType(); + + return rootElementType; + } + + public bool IsVisible + { + get + { +#if CORECLR + RuntimeType rt = this as RuntimeType; + if (rt != null) + return RuntimeTypeHandle.IsVisible(rt); +#endif //CORECLR + + if (IsGenericParameter) + return true; + + if (HasElementType) + return GetElementType().IsVisible; + + Type type = this; + while (type.IsNested) + { + if (!type.IsNestedPublic) + return false; + + // this should be null for non-nested types. + type = type.DeclaringType; + } + + // Now "type" should be a top level type + if (!type.IsPublic) + return false; + + if (IsGenericType && !IsGenericTypeDefinition) + { + foreach (Type t in GetGenericArguments()) + { + if (!t.IsVisible) + return false; + } + } + + return true; + } + } + + public virtual Type[] FindInterfaces(TypeFilter filter, object filterCriteria) + { + if (filter == null) + throw new ArgumentNullException(nameof(filter)); + + Type[] c = GetInterfaces(); + int cnt = 0; + for (int i = 0; i < c.Length; i++) + { + if (!filter(c[i], filterCriteria)) + c[i] = null; + else + cnt++; + } + if (cnt == c.Length) + return c; + + Type[] ret = new Type[cnt]; + cnt = 0; + for (int i = 0; i < c.Length; i++) + { + if (c[i] != null) + ret[cnt++] = c[i]; + } + return ret; + } + + public virtual MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria) + { + // Define the work arrays + MethodInfo[] m = null; + ConstructorInfo[] c = null; + FieldInfo[] f = null; + PropertyInfo[] p = null; + EventInfo[] e = null; + Type[] t = null; + + int i = 0; + int cnt = 0; // Total Matchs + + // Check the methods + if ((memberType & MemberTypes.Method) != 0) + { + m = GetMethods(bindingAttr); + if (filter != null) + { + for (i = 0; i < m.Length; i++) + if (!filter(m[i], filterCriteria)) + m[i] = null; + else + cnt++; + } + else + { + cnt += m.Length; + } + } + + // Check the constructors + if ((memberType & MemberTypes.Constructor) != 0) + { + c = GetConstructors(bindingAttr); + if (filter != null) + { + for (i = 0; i < c.Length; i++) + if (!filter(c[i], filterCriteria)) + c[i] = null; + else + cnt++; + } + else + { + cnt += c.Length; + } + } + + // Check the fields + if ((memberType & MemberTypes.Field) != 0) + { + f = GetFields(bindingAttr); + if (filter != null) + { + for (i = 0; i < f.Length; i++) + if (!filter(f[i], filterCriteria)) + f[i] = null; + else + cnt++; + } + else + { + cnt += f.Length; + } + } + + // Check the Properties + if ((memberType & MemberTypes.Property) != 0) + { + p = GetProperties(bindingAttr); + if (filter != null) + { + for (i = 0; i < p.Length; i++) + if (!filter(p[i], filterCriteria)) + p[i] = null; + else + cnt++; + } + else + { + cnt += p.Length; + } + } + + // Check the Events + if ((memberType & MemberTypes.Event) != 0) + { + e = GetEvents(bindingAttr); + if (filter != null) + { + for (i = 0; i < e.Length; i++) + if (!filter(e[i], filterCriteria)) + e[i] = null; + else + cnt++; + } + else + { + cnt += e.Length; + } + } + + // Check the Types + if ((memberType & MemberTypes.NestedType) != 0) + { + t = GetNestedTypes(bindingAttr); + if (filter != null) + { + for (i = 0; i < t.Length; i++) + if (!filter(t[i], filterCriteria)) + t[i] = null; + else + cnt++; + } + else + { + cnt += t.Length; + } + } + + // Allocate the Member Info + MemberInfo[] ret = new MemberInfo[cnt]; + + // Copy the Methods + cnt = 0; + if (m != null) + { + for (i = 0; i < m.Length; i++) + if (m[i] != null) + ret[cnt++] = m[i]; + } + + // Copy the Constructors + if (c != null) + { + for (i = 0; i < c.Length; i++) + if (c[i] != null) + ret[cnt++] = c[i]; + } + + // Copy the Fields + if (f != null) + { + for (i = 0; i < f.Length; i++) + if (f[i] != null) + ret[cnt++] = f[i]; + } + + // Copy the Properties + if (p != null) + { + for (i = 0; i < p.Length; i++) + if (p[i] != null) + ret[cnt++] = p[i]; + } + + // Copy the Events + if (e != null) + { + for (i = 0; i < e.Length; i++) + if (e[i] != null) + ret[cnt++] = e[i]; + } + + // Copy the Types + if (t != null) + { + for (i = 0; i < t.Length; i++) + if (t[i] != null) + ret[cnt++] = t[i]; + } + + return ret; + } + + public virtual bool IsSubclassOf(Type c) + { + Type p = this; + if (p == c) + return false; + while (p != null) + { + if (p == c) + return true; + p = p.BaseType; + } + return false; + } + + public virtual bool IsAssignableFrom(Type c) + { + if (c == null) + return false; + + if (this == c) + return true; + + // For backward-compatibility, we need to special case for the types + // whose UnderlyingSystemType are runtime implemented. + Type toType = this.UnderlyingSystemType; + if (toType.IsRuntimeImplemented()) + return toType.IsAssignableFrom(c); + + // If c is a subclass of this class, then c can be cast to this type. + if (c.IsSubclassOf(this)) + return true; + + if (this.IsInterface) + { + return c.ImplementInterface(this); + } + else if (IsGenericParameter) + { + Type[] constraints = GetGenericParameterConstraints(); + for (int i = 0; i < constraints.Length; i++) + if (!constraints[i].IsAssignableFrom(c)) + return false; + + return true; + } + + return false; + } + + internal bool ImplementInterface(Type ifaceType) + { + Type t = this; + while (t != null) + { + Type[] interfaces = t.GetInterfaces(); + if (interfaces != null) + { + for (int i = 0; i < interfaces.Length; i++) + { + // Interfaces don't derive from other interfaces, they implement them. + // So instead of IsSubclassOf, we should use ImplementInterface instead. + if (interfaces[i] == ifaceType || + (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType))) + return true; + } + } + + t = t.BaseType; + } + + return false; + } + + // FilterAttribute + // This method will search for a member based upon the attribute passed in. + // filterCriteria -- an Int32 representing the attribute + private static bool FilterAttributeImpl(MemberInfo m, object filterCriteria) + { + // Check that the criteria object is an Integer object + if (filterCriteria == null) + throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt); + + switch (m.MemberType) + { + case MemberTypes.Constructor: + case MemberTypes.Method: + { + MethodAttributes criteria = 0; + try + { + int i = (int)filterCriteria; + criteria = (MethodAttributes)i; + } + catch + { + throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt); + } + + + MethodAttributes attr; + if (m.MemberType == MemberTypes.Method) + attr = ((MethodInfo)m).Attributes; + else + attr = ((ConstructorInfo)m).Attributes; + + if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask)) + return false; + if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0) + return false; + if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0) + return false; + if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0) + return false; + if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0) + return false; + if (((criteria & MethodAttributes.SpecialName) != 0) && (attr & MethodAttributes.SpecialName) == 0) + return false; + return true; + } + case MemberTypes.Field: + { + FieldAttributes criteria = 0; + try + { + int i = (int)filterCriteria; + criteria = (FieldAttributes)i; + } + catch + { + throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt); + } + + FieldAttributes attr = ((FieldInfo)m).Attributes; + if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask)) + return false; + if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0) + return false; + if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0) + return false; + if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0) + return false; + if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0) + return false; + if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0) + return false; + return true; + } + } + + return false; + } + + // FilterName + // This method will filter based upon the name. A partial wildcard + // at the end of the string is supported. + // filterCriteria -- This is the string name + private static bool FilterNameImpl(MemberInfo m, object filterCriteria) + { + // Check that the criteria object is a String object + if (filterCriteria == null || !(filterCriteria is string)) + throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString); + + // At the moment this fails if its done on a single line.... + string str = ((string)filterCriteria); + str = str.Trim(); + + string name = m.Name; + // Get the nested class name only, as opposed to the mangled one + if (m.MemberType == MemberTypes.NestedType) + name = name.Substring(name.LastIndexOf('+') + 1); + // Check to see if this is a prefix or exact match requirement + if (str.Length > 0 && str[str.Length - 1] == '*') + { + str = str.Substring(0, str.Length - 1); + return (name.StartsWith(str, StringComparison.Ordinal)); + } + + return (name.Equals(str)); + } + + // FilterIgnoreCase + // This delegate will do a name search but does it with the + // ignore case specified. + private static bool FilterNameIgnoreCaseImpl(MemberInfo m, object filterCriteria) + { + // Check that the criteria object is a String object + if (filterCriteria == null || !(filterCriteria is string)) + throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString); + + string str = (string)filterCriteria; + str = str.Trim(); + + string name = m.Name; + // Get the nested class name only, as opposed to the mangled one + if (m.MemberType == MemberTypes.NestedType) + name = name.Substring(name.LastIndexOf('+') + 1); + // Check to see if this is a prefix or exact match requirement + if (str.Length > 0 && str[str.Length - 1] == '*') + { + str = str.Substring(0, str.Length - 1); + return (string.Compare(name, 0, str, 0, str.Length, StringComparison.OrdinalIgnoreCase) == 0); + } + + return (string.Compare(str, name, StringComparison.OrdinalIgnoreCase) == 0); + } + } +} + diff --git a/src/mscorlib/src/System/Type.cs b/src/mscorlib/src/System/Type.cs index 78e587d75a..09a72aaef4 100644 --- a/src/mscorlib/src/System/Type.cs +++ b/src/mscorlib/src/System/Type.cs @@ -2,1865 +2,340 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// -// -// -// Implements System.Type -// -// ====================================================================================== +using System.Reflection; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; namespace System { - using System; - using System.Reflection; - using System.Threading; - using System.Runtime; - using System.Runtime.Remoting; - using System.Runtime.InteropServices; - using System.Runtime.CompilerServices; - using System.Security; - using System.Collections; - using System.Collections.Generic; - using System.Runtime.Versioning; - using System.Diagnostics.Contracts; - using CultureInfo = System.Globalization.CultureInfo; - using StackCrawlMark = System.Threading.StackCrawlMark; - using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute; - - [Serializable] - public abstract class Type : MemberInfo, IReflect + public abstract partial class Type : MemberInfo, IReflect { - // - // System.Type is appdomain agile type. Appdomain agile types cannot have precise static constructors. Make - // sure to never introduce one here! - // - public static readonly MemberFilter FilterAttribute = new MemberFilter(__Filters.Instance.FilterAttribute); - public static readonly MemberFilter FilterName = new MemberFilter(__Filters.Instance.FilterName); - public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter(__Filters.Instance.FilterIgnoreCase); - - public static readonly Object Missing = System.Reflection.Missing.Value; - - public static readonly char Delimiter = '.'; - - // EmptyTypes is used to indicate that we are looking for someting without any parameters. - public readonly static Type[] EmptyTypes = EmptyArray<Type>.Value; - - // The Default binder. We create a single one and expose that. - private static Binder defaultBinder; - - protected Type() { } + public override MemberTypes MemberType => MemberTypes.TypeInfo; - // MemberInfo Methods.... - // The Member type Field. - public override MemberTypes MemberType - { - get { return System.Reflection.MemberTypes.TypeInfo; } - } + public new Type GetType() => base.GetType(); - // Return the class that declared this type. - public override Type DeclaringType - { - get { return null; } - } + public abstract string Namespace { get; } + public abstract string AssemblyQualifiedName { get; } + public abstract string FullName { get; } - public virtual MethodBase DeclaringMethod { get { return null; } } + public abstract Assembly Assembly { get; } + public abstract new Module Module { get; } - // Return the class that was used to obtain this type. - public override Type ReflectedType - { - get { return null; } - } + public bool IsNested => DeclaringType != null; + public override Type DeclaringType => null; + public virtual MethodBase DeclaringMethod => null; - //////////////////////////////////////////////////////////////////////////////// - // This is a static method that returns a Class based upon the name of the class - // (this name needs to be fully qualified with the package name and is - // case-sensitive by default). - //// + public override Type ReflectedType => null; + public abstract Type UnderlyingSystemType { get; } - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type GetType(String typeName, bool throwOnError, bool ignoreCase) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RuntimeType.GetType(typeName, throwOnError, ignoreCase, false, ref stackMark); - } + public bool IsArray => IsArrayImpl(); + protected abstract bool IsArrayImpl(); + public bool IsByRef => IsByRefImpl(); + protected abstract bool IsByRefImpl(); + public bool IsPointer => IsPointerImpl(); + protected abstract bool IsPointerImpl(); + public virtual bool IsConstructedGenericType { get { throw NotImplemented.ByDesign; } } + public virtual bool IsGenericParameter => false; + public virtual bool IsGenericType => false; + public virtual bool IsGenericTypeDefinition => false; - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type GetType(String typeName, bool throwOnError) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RuntimeType.GetType(typeName, throwOnError, false, false, ref stackMark); - } + public virtual bool IsSZArray { get { throw NotImplemented.ByDesign; } } - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type GetType(String typeName) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return RuntimeType.GetType(typeName, false, false, false, ref stackMark); - } + public bool HasElementType => HasElementTypeImpl(); + protected abstract bool HasElementTypeImpl(); + public abstract Type GetElementType(); - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type GetType( - string typeName, - Func<AssemblyName, Assembly> assemblyResolver, - Func<Assembly, string, bool, Type> typeResolver) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark); - } + public virtual int GetArrayRank() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type GetType( - string typeName, - Func<AssemblyName, Assembly> assemblyResolver, - Func<Assembly, string, bool, Type> typeResolver, - bool throwOnError) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark); - } - - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type GetType( - string typeName, - Func<AssemblyName, Assembly> assemblyResolver, - Func<Assembly, string, bool, Type> typeResolver, - bool throwOnError, - bool ignoreCase) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); - } - - [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - public static Type ReflectionOnlyGetType(String typeName, bool throwIfNotFound, bool ignoreCase) - { - if (typeName == null) - throw new ArgumentNullException(nameof(typeName)); - if (typeName.Length == 0 && throwIfNotFound) - throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr")); - throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReflectionOnlyGetType")); - } - - public virtual Type MakePointerType() { throw new NotSupportedException(); } - public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } } - public virtual Type MakeByRefType() { throw new NotSupportedException(); } - public virtual Type MakeArrayType() { throw new NotSupportedException(); } - public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); } - - //////////////////////////////////////////////////////////////////////////////// - // This will return a class based upon the progID. This is provided for - // COM classic support. Program ID's are not used in COM+ because they - // have been superceded by namespace. (This routine is called this instead - // of getClass() because of the name conflict with the first method above.) - // - // param progID: the progID of the class to retrieve - // returns: the class object associated to the progID - //// - public static Type GetTypeFromProgID(String progID) - { - return RuntimeType.GetTypeFromProgIDImpl(progID, null, false); - } - - //////////////////////////////////////////////////////////////////////////////// - // This will return a class based upon the progID. This is provided for - // COM classic support. Program ID's are not used in COM+ because they - // have been superceded by namespace. (This routine is called this instead - // of getClass() because of the name conflict with the first method above.) - // - // param progID: the progID of the class to retrieve - // returns: the class object associated to the progID - //// - public static Type GetTypeFromProgID(String progID, bool throwOnError) - { - return RuntimeType.GetTypeFromProgIDImpl(progID, null, throwOnError); - } + public virtual Type GetGenericTypeDefinition() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } + public virtual Type[] GenericTypeArguments => (IsGenericType && !IsGenericTypeDefinition) ? GetGenericArguments() : Array.Empty<Type>(); + public virtual Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } - public static Type GetTypeFromProgID(String progID, String server) - { - return RuntimeType.GetTypeFromProgIDImpl(progID, server, false); - } - - public static Type GetTypeFromProgID(String progID, String server, bool throwOnError) - { - return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError); - } - - //////////////////////////////////////////////////////////////////////////////// - // This will return a class based upon the CLSID. This is provided for - // COM classic support. - // - // param CLSID: the CLSID of the class to retrieve - // returns: the class object associated to the CLSID - //// - public static Type GetTypeFromCLSID(Guid clsid) - { - return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false); - } - - public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError) - { - return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError); - } - - public static Type GetTypeFromCLSID(Guid clsid, String server) - { - return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, false); - } - - public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError) - { - return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError); - } - - // GetTypeCode - // This method will return a TypeCode for the passed - // type. - public static TypeCode GetTypeCode(Type type) - { - if (type == null) - return TypeCode.Empty; - return type.GetTypeCodeImpl(); - } - - protected virtual TypeCode GetTypeCodeImpl() - { - // System.RuntimeType overrides GetTypeCodeInternal - // so we can assume that this is not a runtime type - - // this is true for EnumBuilder but not the other System.Type subclasses in BCL - if (this != UnderlyingSystemType && UnderlyingSystemType != null) - return Type.GetTypeCode(UnderlyingSystemType); - - return TypeCode.Object; - } - - // Property representing the GUID associated with a class. - public abstract Guid GUID - { - get; - } - - // Return the Default binder used by the system. - static public Binder DefaultBinder - { - get - { - // Allocate the default binder if it hasn't been allocated yet. - if (defaultBinder == null) - CreateBinder(); - return defaultBinder; - } - } - - static private void CreateBinder() - { - if (defaultBinder == null) - { - DefaultBinder binder = new DefaultBinder(); - Interlocked.CompareExchange<Binder>(ref defaultBinder, binder, null); - } - } - - // Description of the Binding Process. - // We must invoke a method that is accessable and for which the provided - // parameters have the most specific match. A method may be called if - // 1. The number of parameters in the method declaration equals the number of - // arguments provided to the invocation - // 2. The type of each argument can be converted by the binder to the - // type of the type of the parameter. - // - // The binder will find all of the matching methods. These method are found based - // upon the type of binding requested (MethodInvoke, Get/Set Properties). The set - // of methods is filtered by the name, number of arguments and a set of search modifiers - // defined in the Binder. - // - // After the method is selected, it will be invoked. Accessability is checked - // at that point. The search may be control which set of methods are searched based - // upon the accessibility attribute associated with the method. - // - // The BindToMethod method is responsible for selecting the method to be invoked. - // For the default binder, the most specific method will be selected. - // - // This will invoke a specific member... - - abstract public Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, - Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters); - - [DebuggerStepThroughAttribute] - [Diagnostics.DebuggerHidden] - public Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture) - { - return InvokeMember(name, invokeAttr, binder, target, args, null, culture, null); - } - - [DebuggerStepThroughAttribute] - [Diagnostics.DebuggerHidden] - public Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args) - { - return InvokeMember(name, invokeAttr, binder, target, args, null, null, null); - } - - - // Module Property associated with a class. - public new abstract Module Module { get; } - - // Assembly Property associated with a class. - public abstract Assembly Assembly - { - [Pure] - get; - } - - // Assembly Property associated with a class. - // A class handle is a unique integer value associated with - // each class. The handle is unique during the process life time. - public virtual RuntimeTypeHandle TypeHandle - { - [Pure] - get - { - throw new NotSupportedException(); - } - } - - internal virtual RuntimeTypeHandle GetTypeHandleInternal() - { - return TypeHandle; - } - - public static RuntimeTypeHandle GetTypeHandle(Object o) + public virtual int GenericParameterPosition { get { throw new InvalidOperationException(SR.Arg_NotGenericParameter); } } + public virtual GenericParameterAttributes GenericParameterAttributes { get { throw new NotSupportedException(); } } + public virtual Type[] GetGenericParameterConstraints() { - if (o == null) - throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle")); - return new RuntimeTypeHandle((RuntimeType)o.GetType()); + if (!IsGenericParameter) + throw new InvalidOperationException(SR.Arg_NotGenericParameter); + throw new InvalidOperationException(); } - // Given a class handle, this will return the class for that handle. - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle); + public TypeAttributes Attributes => GetAttributeFlagsImpl(); + protected abstract TypeAttributes GetAttributeFlagsImpl(); - [Pure] - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle); + public bool IsAbstract => (GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0; + public bool IsImport => (GetAttributeFlagsImpl() & TypeAttributes.Import) != 0; + public bool IsSealed => (GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0; + public bool IsSpecialName => (GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0; + public bool IsClass => (GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType; - // Return the fully qualified name. The name does contain the namespace. - public abstract String FullName - { - [Pure] - get; - } - - // Return the name space of the class. - public abstract String Namespace - { - [Pure] - get; - } + public bool IsNestedAssembly => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; + public bool IsNestedFamANDAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; + public bool IsNestedFamily => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; + public bool IsNestedFamORAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; + public bool IsNestedPrivate => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; + public bool IsNestedPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; + public bool IsNotPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; + public bool IsPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public; + public bool IsAutoLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; + public bool IsExplicitLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; + public bool IsLayoutSequential => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; - public abstract String AssemblyQualifiedName - { - [Pure] - get; - } + public bool IsAnsiClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; + public bool IsAutoClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; + public bool IsUnicodeClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; + public bool IsCOMObject => IsCOMObjectImpl(); + protected abstract bool IsCOMObjectImpl(); + public bool IsContextful => IsContextfulImpl(); + protected virtual bool IsContextfulImpl() => false; - [Pure] - public virtual int GetArrayRank() - { - Contract.Ensures(Contract.Result<int>() >= 0); - throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); - } + public virtual bool IsEnum => IsSubclassOf(typeof(Enum)); + public bool IsMarshalByRef => IsMarshalByRefImpl(); + protected virtual bool IsMarshalByRefImpl() => false; + public bool IsPrimitive => IsPrimitiveImpl(); + protected abstract bool IsPrimitiveImpl(); + public bool IsValueType => IsValueTypeImpl(); + protected virtual bool IsValueTypeImpl() => IsSubclassOf(typeof(ValueType)); - // Returns the base class for a class. If this is an interface or has - // no base class null is returned. Object is the only Type that does not - // have a base class. - public abstract Type BaseType - { - [Pure] - get; - } + public virtual bool IsSecurityCritical { get { throw NotImplemented.ByDesign; } } + public virtual bool IsSecuritySafeCritical { get { throw NotImplemented.ByDesign; } } + public virtual bool IsSecurityTransparent { get { throw NotImplemented.ByDesign; } } + public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } } + public ConstructorInfo TypeInitializer => GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, Type.EmptyTypes, null); - // GetConstructor - // This method will search for the specified constructor. For constructors, - // unlike everything else, the default is to not look for static methods. The - // reason is that we don't typically expose the class initializer. - public ConstructorInfo GetConstructor(BindingFlags bindingAttr, - Binder binder, - CallingConventions callConvention, - Type[] types, - ParameterModifier[] modifiers) + public ConstructorInfo GetConstructor(Type[] types) => GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null); + public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetConstructor(bindingAttr, binder, CallingConventions.Any, types, modifiers); + public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { - // Must provide some types (Type[0] for nothing) if (types == null) throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); for (int i = 0; i < types.Length; i++) + { if (types[i] == null) throw new ArgumentNullException(nameof(types)); + } return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers); } + protected abstract ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers); - public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) - { - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - for (int i = 0; i < types.Length; i++) - if (types[i] == null) - throw new ArgumentNullException(nameof(types)); - return GetConstructorImpl(bindingAttr, binder, CallingConventions.Any, types, modifiers); - } - - public ConstructorInfo GetConstructor(Type[] types) - { - // The arguments are checked in the called version of GetConstructor. - return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null); - } + public ConstructorInfo[] GetConstructors() => GetConstructors(BindingFlags.Public | BindingFlags.Instance); + public abstract ConstructorInfo[] GetConstructors(BindingFlags bindingAttr); - abstract protected ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, - Binder binder, - CallingConventions callConvention, - Type[] types, - ParameterModifier[] modifiers); - - // GetConstructors() - // This routine will return an array of all constructors supported by the class. - // Unlike everything else, the default is to not look for static methods. The - // reason is that we don't typically expose the class initializer. - public ConstructorInfo[] GetConstructors() - { - return GetConstructors(BindingFlags.Public | BindingFlags.Instance); - } + public EventInfo GetEvent(string name) => GetEvent(name, Type.DefaultLookup); + public abstract EventInfo GetEvent(string name, BindingFlags bindingAttr); - abstract public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr); + public virtual EventInfo[] GetEvents() => GetEvents(Type.DefaultLookup); + public abstract EventInfo[] GetEvents(BindingFlags bindingAttr); - public ConstructorInfo TypeInitializer - { - get - { - return GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, - null, - CallingConventions.Any, - Type.EmptyTypes, - null); - } - } + public FieldInfo GetField(string name) => GetField(name, Type.DefaultLookup); + public abstract FieldInfo GetField(string name, BindingFlags bindingAttr); + public FieldInfo[] GetFields() => GetFields(Type.DefaultLookup); + public abstract FieldInfo[] GetFields(BindingFlags bindingAttr); - // Return a method based upon the passed criteria. The name of the method - // must be provided, and exception is thrown if it is not. The bindingAttr - // parameter indicates if non-public methods should be searched. The types - // array indicates the types of the parameters being looked for. - public MethodInfo GetMethod(String name, - BindingFlags bindingAttr, - Binder binder, - CallingConventions callConvention, - Type[] types, - ParameterModifier[] modifiers) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - for (int i = 0; i < types.Length; i++) - if (types[i] == null) - throw new ArgumentNullException(nameof(types)); - return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers); - } + public MemberInfo[] GetMember(string name) => GetMember(name, Type.DefaultLookup); + public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr) => GetMember(name, MemberTypes.All, bindingAttr); + public virtual MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } - public MethodInfo GetMethod(String name, - BindingFlags bindingAttr, - Binder binder, - Type[] types, - ParameterModifier[] modifiers) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - for (int i = 0; i < types.Length; i++) - if (types[i] == null) - throw new ArgumentNullException(nameof(types)); - return GetMethodImpl(name, bindingAttr, binder, CallingConventions.Any, types, modifiers); - } + public MemberInfo[] GetMembers() => GetMembers(Type.DefaultLookup); + public abstract MemberInfo[] GetMembers(BindingFlags bindingAttr); - public MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers) + public MethodInfo GetMethod(string name) => GetMethod(name, Type.DefaultLookup); + public MethodInfo GetMethod(string name, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - for (int i = 0; i < types.Length; i++) - if (types[i] == null) - throw new ArgumentNullException(nameof(types)); - return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, modifiers); + return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null); } - public MethodInfo GetMethod(String name, Type[] types) + public MethodInfo GetMethod(string name, Type[] types) => GetMethod(name, types, null); + public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, Type.DefaultLookup, null, types, modifiers); + public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, bindingAttr, binder, CallingConventions.Any, types, modifiers); + public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { if (name == null) throw new ArgumentNullException(nameof(name)); if (types == null) throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); for (int i = 0; i < types.Length; i++) + { if (types[i] == null) throw new ArgumentNullException(nameof(types)); - return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, null); - } - - public MethodInfo GetMethod(String name, BindingFlags bindingAttr) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - Contract.EndContractBlock(); - return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null); - } - - public MethodInfo GetMethod(String name) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - Contract.EndContractBlock(); - return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, null, null); - } - - abstract protected MethodInfo GetMethodImpl(String name, - BindingFlags bindingAttr, - Binder binder, - CallingConventions callConvention, - Type[] types, - ParameterModifier[] modifiers); - - - // GetMethods - // This routine will return all the methods implemented by the class - public MethodInfo[] GetMethods() - { - return GetMethods(Type.DefaultLookup); - } - - abstract public MethodInfo[] GetMethods(BindingFlags bindingAttr); - - // GetField - // Get Field will return a specific field based upon name - abstract public FieldInfo GetField(String name, BindingFlags bindingAttr); - - - public FieldInfo GetField(String name) - { - return GetField(name, Type.DefaultLookup); - } - - - // GetFields - // Get fields will return a full array of fields implemented by a class - public FieldInfo[] GetFields() - { - return GetFields(Type.DefaultLookup); - } - abstract public FieldInfo[] GetFields(BindingFlags bindingAttr); - - // GetInterface - // This method will return an interface (as a class) based upon - // the passed in name. - public Type GetInterface(String name) - { - return GetInterface(name, false); - } - abstract public Type GetInterface(String name, bool ignoreCase); - - - // GetInterfaces - // This method will return all of the interfaces implemented by a class - abstract public Type[] GetInterfaces(); - - // FindInterfaces - // This method will filter the interfaces supported the class - public virtual Type[] FindInterfaces(TypeFilter filter, Object filterCriteria) - { - if (filter == null) - throw new ArgumentNullException(nameof(filter)); - Contract.EndContractBlock(); - Type[] c = GetInterfaces(); - int cnt = 0; - for (int i = 0; i < c.Length; i++) - { - if (!filter(c[i], filterCriteria)) - c[i] = null; - else - cnt++; } - if (cnt == c.Length) - return c; - - Type[] ret = new Type[cnt]; - cnt = 0; - for (int i = 0; i < c.Length; i++) - { - if (c[i] != null) - ret[cnt++] = c[i]; - } - return ret; - } - - // GetEvent - // This method will return a event by name if it is found. - // null is returned if the event is not found - - - public EventInfo GetEvent(String name) - { - return GetEvent(name, Type.DefaultLookup); + return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers); } - abstract public EventInfo GetEvent(String name, BindingFlags bindingAttr); - // GetEvents - // This method will return an array of EventInfo. If there are not Events - // an empty array will be returned. - virtual public EventInfo[] GetEvents() - { - return GetEvents(Type.DefaultLookup); - } - abstract public EventInfo[] GetEvents(BindingFlags bindingAttr); + protected abstract MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers); + public MethodInfo[] GetMethods() => GetMethods(Type.DefaultLookup); + public abstract MethodInfo[] GetMethods(BindingFlags bindingAttr); - // Return a property based upon the passed criteria. The nameof the - // parameter must be provided. - public PropertyInfo GetProperty(String name, BindingFlags bindingAttr, Binder binder, - Type returnType, Type[] types, ParameterModifier[] modifiers) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - return GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers); - } + public Type GetNestedType(string name) => GetNestedType(name, Type.DefaultLookup); + public abstract Type GetNestedType(string name, BindingFlags bindingAttr); - public PropertyInfo GetProperty(String name, Type returnType, Type[] types, ParameterModifier[] modifiers) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - return GetPropertyImpl(name, Type.DefaultLookup, null, returnType, types, modifiers); - } + public Type[] GetNestedTypes() => GetNestedTypes(Type.DefaultLookup); + public abstract Type[] GetNestedTypes(BindingFlags bindingAttr); - public PropertyInfo GetProperty(String name, BindingFlags bindingAttr) + public PropertyInfo GetProperty(string name) => GetProperty(name, Type.DefaultLookup); + public PropertyInfo GetProperty(string name, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(nameof(name)); - Contract.EndContractBlock(); return GetPropertyImpl(name, bindingAttr, null, null, null, null); } - public PropertyInfo GetProperty(String name, Type returnType, Type[] types) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - return GetPropertyImpl(name, Type.DefaultLookup, null, returnType, types, null); - } - - public PropertyInfo GetProperty(String name, Type[] types) - { - if (name == null) - throw new ArgumentNullException(nameof(name)); - if (types == null) - throw new ArgumentNullException(nameof(types)); - Contract.EndContractBlock(); - return GetPropertyImpl(name, Type.DefaultLookup, null, null, types, null); - } - - public PropertyInfo GetProperty(String name, Type returnType) + public PropertyInfo GetProperty(string name, Type returnType) { if (name == null) throw new ArgumentNullException(nameof(name)); if (returnType == null) throw new ArgumentNullException(nameof(returnType)); - Contract.EndContractBlock(); return GetPropertyImpl(name, Type.DefaultLookup, null, returnType, null, null); } - public PropertyInfo GetProperty(String name) + public PropertyInfo GetProperty(string name, Type[] types) => GetProperty(name, null, types); + public PropertyInfo GetProperty(string name, Type returnType, Type[] types) => GetProperty(name, returnType, types, null); + public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers) => GetProperty(name, Type.DefaultLookup, null, returnType, types, modifiers); + public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { if (name == null) throw new ArgumentNullException(nameof(name)); - Contract.EndContractBlock(); - return GetPropertyImpl(name, Type.DefaultLookup, null, null, null, null); - } - - protected abstract PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, - Type returnType, Type[] types, ParameterModifier[] modifiers); - - - // GetProperties - // This method will return an array of all of the properties defined - // for a Type. - abstract public PropertyInfo[] GetProperties(BindingFlags bindingAttr); - public PropertyInfo[] GetProperties() - { - return GetProperties(Type.DefaultLookup); - } - - // GetNestedTypes() - // This set of method will return any nested types that are found inside - // of the type. - public Type[] GetNestedTypes() - { - return GetNestedTypes(Type.DefaultLookup); - } - - abstract public Type[] GetNestedTypes(BindingFlags bindingAttr); - - public Type GetNestedType(String name) - { - return GetNestedType(name, Type.DefaultLookup); - } - - abstract public Type GetNestedType(String name, BindingFlags bindingAttr); - - // GetMember - // This method will return all of the members which match the specified string - // passed into the method - public MemberInfo[] GetMember(String name) - { - return GetMember(name, Type.DefaultLookup); - } - - virtual public MemberInfo[] GetMember(String name, BindingFlags bindingAttr) - { - return GetMember(name, MemberTypes.All, bindingAttr); - } - - virtual public MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) - { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); - } - - - // GetMembers - // This will return a Member array of all of the members of a class - public MemberInfo[] GetMembers() - { - return GetMembers(Type.DefaultLookup); - } - abstract public MemberInfo[] GetMembers(BindingFlags bindingAttr); - - // GetDefaultMembers - // This will return a MemberInfo that has been marked with the - // DefaultMemberAttribute - public virtual MemberInfo[] GetDefaultMembers() - { - throw new NotImplementedException(); - } - - // FindMembers - // This will return a filtered version of the member information - public virtual MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, Object filterCriteria) - { - // Define the work arrays - MethodInfo[] m = null; - ConstructorInfo[] c = null; - FieldInfo[] f = null; - PropertyInfo[] p = null; - EventInfo[] e = null; - Type[] t = null; - - int i = 0; - int cnt = 0; // Total Matchs - - // Check the methods - if ((memberType & System.Reflection.MemberTypes.Method) != 0) - { - m = GetMethods(bindingAttr); - if (filter != null) - { - for (i = 0; i < m.Length; i++) - if (!filter(m[i], filterCriteria)) - m[i] = null; - else - cnt++; - } - else - { - cnt += m.Length; - } - } - - // Check the constructors - if ((memberType & System.Reflection.MemberTypes.Constructor) != 0) - { - c = GetConstructors(bindingAttr); - if (filter != null) - { - for (i = 0; i < c.Length; i++) - if (!filter(c[i], filterCriteria)) - c[i] = null; - else - cnt++; - } - else - { - cnt += c.Length; - } - } - - // Check the fields - if ((memberType & System.Reflection.MemberTypes.Field) != 0) - { - f = GetFields(bindingAttr); - if (filter != null) - { - for (i = 0; i < f.Length; i++) - if (!filter(f[i], filterCriteria)) - f[i] = null; - else - cnt++; - } - else - { - cnt += f.Length; - } - } - - // Check the Properties - if ((memberType & System.Reflection.MemberTypes.Property) != 0) - { - p = GetProperties(bindingAttr); - if (filter != null) - { - for (i = 0; i < p.Length; i++) - if (!filter(p[i], filterCriteria)) - p[i] = null; - else - cnt++; - } - else - { - cnt += p.Length; - } - } - - // Check the Events - if ((memberType & System.Reflection.MemberTypes.Event) != 0) - { - e = GetEvents(bindingAttr); - if (filter != null) - { - for (i = 0; i < e.Length; i++) - if (!filter(e[i], filterCriteria)) - e[i] = null; - else - cnt++; - } - else - { - cnt += e.Length; - } - } - - // Check the Types - if ((memberType & System.Reflection.MemberTypes.NestedType) != 0) - { - t = GetNestedTypes(bindingAttr); - if (filter != null) - { - for (i = 0; i < t.Length; i++) - if (!filter(t[i], filterCriteria)) - t[i] = null; - else - cnt++; - } - else - { - cnt += t.Length; - } - } - - // Allocate the Member Info - MemberInfo[] ret = new MemberInfo[cnt]; - - // Copy the Methods - cnt = 0; - if (m != null) - { - for (i = 0; i < m.Length; i++) - if (m[i] != null) - ret[cnt++] = m[i]; - } - - // Copy the Constructors - if (c != null) - { - for (i = 0; i < c.Length; i++) - if (c[i] != null) - ret[cnt++] = c[i]; - } - - // Copy the Fields - if (f != null) - { - for (i = 0; i < f.Length; i++) - if (f[i] != null) - ret[cnt++] = f[i]; - } - - // Copy the Properties - if (p != null) - { - for (i = 0; i < p.Length; i++) - if (p[i] != null) - ret[cnt++] = p[i]; - } - - // Copy the Events - if (e != null) - { - for (i = 0; i < e.Length; i++) - if (e[i] != null) - ret[cnt++] = e[i]; - } - - // Copy the Types - if (t != null) - { - for (i = 0; i < t.Length; i++) - if (t[i] != null) - ret[cnt++] = t[i]; - } - - return ret; - } - - //////////////////////////////////////////////////////////////////////////////// - // - // Attributes - // - // The attributes are all treated as read-only properties on a class. Most of - // these boolean properties have flag values defined in this class and act like - // a bit mask of attributes. There are also a set of boolean properties that - // relate to the classes relationship to other classes and to the state of the - // class inside the runtime. - // - //////////////////////////////////////////////////////////////////////////////// - - public bool IsNested - { - [Pure] - get - { - return DeclaringType != null; - } - } - - // The attribute property on the Type. - public TypeAttributes Attributes - { - [Pure] - get { return GetAttributeFlagsImpl(); } - } - - public virtual GenericParameterAttributes GenericParameterAttributes - { - get { throw new NotSupportedException(); } - } - - public bool IsVisible - { - [Pure] - get - { - RuntimeType rt = this as RuntimeType; - if (rt != null) - return RuntimeTypeHandle.IsVisible(rt); - - if (IsGenericParameter) - return true; - - if (HasElementType) - return GetElementType().IsVisible; - - Type type = this; - while (type.IsNested) - { - if (!type.IsNestedPublic) - return false; - - // this should be null for non-nested types. - type = type.DeclaringType; - } - - // Now "type" should be a top level type - if (!type.IsPublic) - return false; - - if (IsGenericType && !IsGenericTypeDefinition) - { - foreach (Type t in GetGenericArguments()) - { - if (!t.IsVisible) - return false; - } - } - - return true; - } - } - - public bool IsNotPublic - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic); } - } - - public bool IsPublic - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public); } - } - - public bool IsNestedPublic - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic); } - } - - public bool IsNestedPrivate - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate); } - } - public bool IsNestedFamily - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily); } - } - public bool IsNestedAssembly - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly); } - } - public bool IsNestedFamANDAssem - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem); } - } - public bool IsNestedFamORAssem - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem); } - } - - public bool IsAutoLayout - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout); } - } - public bool IsLayoutSequential - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout); } - } - public bool IsExplicitLayout - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout); } - } - - public bool IsClass - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType); } - } - - public bool IsInterface - { - [Pure] - get - { - RuntimeType rt = this as RuntimeType; - if (rt != null) - return RuntimeTypeHandle.IsInterface(rt); - - return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface); - } - } - - public bool IsValueType - { - [Pure] - get { return IsValueTypeImpl(); } - } - - public bool IsAbstract - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0); } - } - - public bool IsSealed - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0); } - } - - public virtual bool IsEnum - { - [Pure] - get - { - // This will return false for a non-runtime Type object unless it overrides IsSubclassOf. - return IsSubclassOf(RuntimeType.EnumType); - } - } - - public bool IsSpecialName - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0); } - } - - public bool IsImport - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0); } - } - - public virtual bool IsSerializable - { - [Pure] - get - { - if ((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0) - return true; - - RuntimeType rt = this.UnderlyingSystemType as RuntimeType; - - if (rt != null) - return rt.IsSpecialSerializableType(); - - return false; - } - } - - public bool IsAnsiClass - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass); } - } - - public bool IsUnicodeClass - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass); } - } - - public bool IsAutoClass - { - [Pure] - get { return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass); } - } - - // These are not backed up by attributes. Instead they are implemented - // based internally. - public bool IsArray - { - [Pure] - get { return IsArrayImpl(); } - } - - public virtual bool IsSZArray - { - [Pure] - get { throw new NotImplementedException(); } - } - - public virtual bool IsGenericType - { - [Pure] - get { return false; } - } - - public virtual bool IsGenericTypeDefinition - { - [Pure] - get { return false; } - } - - public virtual bool IsConstructedGenericType - { - [Pure] - get { throw new NotImplementedException(); } - } - - public virtual bool IsGenericParameter - { - [Pure] - get { return false; } - } - - public virtual int GenericParameterPosition - { - [Pure] - get { throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter")); } - } - - public virtual bool ContainsGenericParameters - { - [Pure] - get - { - if (HasElementType) - return GetRootElementType().ContainsGenericParameters; - - if (IsGenericParameter) - return true; - - if (!IsGenericType) - return false; - - Type[] genericArguments = GetGenericArguments(); - for (int i = 0; i < genericArguments.Length; i++) - { - if (genericArguments[i].ContainsGenericParameters) - return true; - } - - return false; - } - } - - [Pure] - public virtual Type[] GetGenericParameterConstraints() - { - if (!IsGenericParameter) - throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter")); - Contract.EndContractBlock(); - - throw new InvalidOperationException(); - } - - public bool IsByRef - { - [Pure] - get { return IsByRefImpl(); } - } - public bool IsPointer - { - [Pure] - get { return IsPointerImpl(); } - } - public bool IsPrimitive - { - [Pure] - get { return IsPrimitiveImpl(); } - } - public bool IsCOMObject - { - [Pure] - get { return IsCOMObjectImpl(); } - } - -#if FEATURE_COMINTEROP - internal bool IsWindowsRuntimeObject - { - [Pure] - get { return IsWindowsRuntimeObjectImpl(); } - } - - internal bool IsExportedToWindowsRuntime - { - [Pure] - get { return IsExportedToWindowsRuntimeImpl(); } - } -#endif // FEATURE_COMINTEROP - - public bool HasElementType - { - [Pure] - get { return HasElementTypeImpl(); } - } - - public bool IsContextful - { - [Pure] - get { return IsContextfulImpl(); } - } - - public bool IsMarshalByRef - { - [Pure] - get { return IsMarshalByRefImpl(); } - } - - // Protected routine to determine if this class represents a value class - // The default implementation of IsValueTypeImpl never returns true for non-runtime types. - protected virtual bool IsValueTypeImpl() - { - // Note that typeof(Enum) and typeof(ValueType) are not themselves value types. - // But there is no point excluding them here because customer derived System.Type - // (non-runtime type) objects can never be equal to a runtime type, which typeof(XXX) is. - // Ideally we should throw a NotImplementedException here or just return false because - // customer implementations of IsSubclassOf should never return true between a non-runtime - // type and a runtime type. There is no benefits in making that breaking change though. - - return IsSubclassOf(RuntimeType.ValueType); - } - - // Protected routine to get the attributes. - abstract protected TypeAttributes GetAttributeFlagsImpl(); - - // Protected routine to determine if this class represents an Array - abstract protected bool IsArrayImpl(); - - // Protected routine to determine if this class is a ByRef - abstract protected bool IsByRefImpl(); - - // Protected routine to determine if this class is a Pointer - abstract protected bool IsPointerImpl(); - - // Protected routine to determine if this class represents a primitive type - abstract protected bool IsPrimitiveImpl(); - - // Protected routine to determine if this class represents a COM object - abstract protected bool IsCOMObjectImpl(); - -#if FEATURE_COMINTEROP - // Protected routine to determine if this class represents a Windows Runtime object - virtual internal bool IsWindowsRuntimeObjectImpl() - { - throw new NotImplementedException(); - } - - // Determines if this type is exported to WinRT (i.e. is an activatable class in a managed .winmd) - virtual internal bool IsExportedToWindowsRuntimeImpl() - { - throw new NotImplementedException(); + if (types == null) + throw new ArgumentNullException(nameof(types)); + return GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers); } -#endif // FEATURE_COMINTEROP - public virtual Type MakeGenericType(params Type[] typeArguments) - { - Contract.Ensures(Contract.Result<Type>() != null); - throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); - } + protected abstract PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers); + public PropertyInfo[] GetProperties() => GetProperties(Type.DefaultLookup); + public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr); - // Protected routine to determine if this class is contextful - protected virtual bool IsContextfulImpl() - { - return false; - } + public virtual MemberInfo[] GetDefaultMembers() { throw NotImplemented.ByDesign; } - // Protected routine to determine if this class is marshaled by ref - protected virtual bool IsMarshalByRefImpl() + public virtual RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } } + public static RuntimeTypeHandle GetTypeHandle(object o) { - return false; + if (o == null) + throw new ArgumentNullException(null, SR.Arg_InvalidHandle); + Type type = o.GetType(); + return type.TypeHandle; } - [Pure] - abstract public Type GetElementType(); - - [Pure] - public virtual Type[] GetGenericArguments() + public static Type[] GetTypeArray(object[] args) { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); - } + if (args == null) + throw new ArgumentNullException(nameof(args)); - public virtual Type[] GenericTypeArguments - { - get + Type[] cls = new Type[args.Length]; + for (int i = 0; i < cls.Length; i++) { - if (IsGenericType && !IsGenericTypeDefinition) - { - return GetGenericArguments(); - } - else - { - return Type.EmptyTypes; - } + if (args[i] == null) + throw new ArgumentNullException(); + cls[i] = args[i].GetType(); } + return cls; } - [Pure] - public virtual Type GetGenericTypeDefinition() - { - Contract.Ensures(Contract.Result<Type>() != null); - throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); - } - - [Pure] - abstract protected bool HasElementTypeImpl(); - - internal Type GetRootElementType() + public static TypeCode GetTypeCode(Type type) { - Type rootElementType = this; - - while (rootElementType.HasElementType) - rootElementType = rootElementType.GetElementType(); - - return rootElementType; + if (type == null) + return TypeCode.Empty; + return type.GetTypeCodeImpl(); } - - #region Enum methods - - // Default implementations of GetEnumNames, GetEnumValues, and GetEnumUnderlyingType - // Subclass of types can override these methods. - - public virtual string[] GetEnumNames() + protected virtual TypeCode GetTypeCodeImpl() { - if (!IsEnum) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); - Contract.Ensures(Contract.Result<String[]>() != null); + if (this != UnderlyingSystemType && UnderlyingSystemType != null) + return Type.GetTypeCode(UnderlyingSystemType); - string[] names; - Array values; - GetEnumData(out names, out values); - return names; + return TypeCode.Object; } - // We don't support GetEnumValues in the default implementation because we cannot create an array of - // a non-runtime type. If there is strong need we can consider returning an object or int64 array. - public virtual Array GetEnumValues() - { - if (!IsEnum) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); - Contract.Ensures(Contract.Result<Array>() != null); + public abstract Guid GUID { get; } - throw new NotImplementedException(); - } + public static Type GetTypeFromCLSID(Guid clsid) => GetTypeFromCLSID(clsid, null, throwOnError: false); + public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError) => GetTypeFromCLSID(clsid, null, throwOnError: throwOnError); + public static Type GetTypeFromCLSID(Guid clsid, string server) => GetTypeFromCLSID(clsid, server, throwOnError: false); - // Returns the enum values as an object array. - private Array GetEnumRawConstantValues() - { - string[] names; - Array values; - GetEnumData(out names, out values); - return values; - } + public static Type GetTypeFromProgID(string progID) => GetTypeFromProgID(progID, null, throwOnError: false); + public static Type GetTypeFromProgID(string progID, bool throwOnError) => GetTypeFromProgID(progID, null, throwOnError: throwOnError); + public static Type GetTypeFromProgID(string progID, string server) => GetTypeFromProgID(progID, server, throwOnError: false); - // This will return enumValues and enumNames sorted by the values. - private void GetEnumData(out string[] enumNames, out Array enumValues) - { - Contract.Ensures(Contract.ValueAtReturn<String[]>(out enumNames) != null); - Contract.Ensures(Contract.ValueAtReturn<Array>(out enumValues) != null); + public abstract Type BaseType { get; } - FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + [DebuggerHidden] + [DebuggerStepThrough] + public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args) => InvokeMember(name, invokeAttr, binder, target, args, null, null, null); - object[] values = new object[flds.Length]; - string[] names = new string[flds.Length]; + [DebuggerHidden] + [DebuggerStepThrough] + public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture) => InvokeMember(name, invokeAttr, binder, target, args, null, culture, null); + public abstract object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters); - for (int i = 0; i < flds.Length; i++) - { - names[i] = flds[i].Name; - values[i] = flds[i].GetRawConstantValue(); - } + public Type GetInterface(string name) => GetInterface(name, ignoreCase: false); + public abstract Type GetInterface(string name, bool ignoreCase); + public abstract Type[] GetInterfaces(); - // Insertion Sort these values in ascending order. - // We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and - // the common case performance will be faster than quick sorting this. - IComparer comparer = Comparer.Default; - for (int i = 1; i < values.Length; i++) - { - int j = i; - string tempStr = names[i]; - object val = values[i]; - bool exchanged = false; - - // Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop. - while (comparer.Compare(values[j - 1], val) > 0) - { - names[j] = names[j - 1]; - values[j] = values[j - 1]; - j--; - exchanged = true; - if (j == 0) - break; - } - - if (exchanged) - { - names[j] = tempStr; - values[j] = val; - } - } + public virtual InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } - enumNames = names; - enumValues = values; - } + public virtual bool IsInstanceOfType(object o) => o == null ? false : IsAssignableFrom(o.GetType()); + public virtual bool IsEquivalentTo(Type other) => this == other; public virtual Type GetEnumUnderlyingType() { if (!IsEnum) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); - Contract.Ensures(Contract.Result<Type>() != null); + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (fields == null || fields.Length != 1) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnum"), "enumType"); + throw new ArgumentException(SR.Argument_InvalidEnum, "enumType"); return fields[0].FieldType; } - - public virtual bool IsEnumDefined(object value) - { - if (value == null) - throw new ArgumentNullException(nameof(value)); - - if (!IsEnum) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); - Contract.EndContractBlock(); - - // Check if both of them are of the same type - Type valueType = value.GetType(); - - // If the value is an Enum then we need to extract the underlying value from it - if (valueType.IsEnum) - { - if (!valueType.IsEquivalentTo(this)) - throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString())); - - valueType = valueType.GetEnumUnderlyingType(); - } - - // If a string is passed in - if (valueType == typeof(string)) - { - string[] names = GetEnumNames(); - if (Array.IndexOf(names, value) >= 0) - return true; - else - return false; - } - - // If an enum or integer value is passed in - if (Type.IsIntegerType(valueType)) - { - Type underlyingType = GetEnumUnderlyingType(); - // We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be. - if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl()) - throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString())); - - Array values = GetEnumRawConstantValues(); - return (BinarySearch(values, value) >= 0); - } - else - { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType")); - } - } - - public virtual string GetEnumName(object value) + public virtual Array GetEnumValues() { - if (value == null) - throw new ArgumentNullException(nameof(value)); - if (!IsEnum) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType"); - Contract.EndContractBlock(); - - Type valueType = value.GetType(); - - if (!(valueType.IsEnum || Type.IsIntegerType(valueType))) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value)); - - Array values = GetEnumRawConstantValues(); - int index = BinarySearch(values, value); - - if (index >= 0) - { - string[] names = GetEnumNames(); - return names[index]; - } - - return null; - } - - // Convert everything to ulong then perform a binary search. - private static int BinarySearch(Array array, object value) - { - ulong[] ulArray = new ulong[array.Length]; - for (int i = 0; i < array.Length; ++i) - ulArray[i] = Enum.ToUInt64(array.GetValue(i)); - - ulong ulValue = Enum.ToUInt64(value); + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); - return Array.BinarySearch(ulArray, ulValue); - } - - internal static bool IsIntegerType(Type t) - { - return (t == typeof(int) || - t == typeof(short) || - t == typeof(ushort) || - t == typeof(byte) || - t == typeof(sbyte) || - t == typeof(uint) || - t == typeof(long) || - t == typeof(ulong) || - t == typeof(char) || - t == typeof(bool)); + // We don't support GetEnumValues in the default implementation because we cannot create an array of + // a non-runtime type. If there is strong need we can consider returning an object or int64 array. + throw NotImplemented.ByDesign; } - #endregion - public virtual bool IsSecurityCritical { [Pure] get { throw new NotImplementedException(); } } - - public virtual bool IsSecuritySafeCritical { [Pure] get { throw new NotImplementedException(); } } - - public virtual bool IsSecurityTransparent { [Pure] get { throw new NotImplementedException(); } } - - internal bool NeedsReflectionSecurityCheck - { - get - { - if (!IsVisible) - { - // Types which are not externally visible require security checks - return true; - } - else if (IsSecurityCritical && !IsSecuritySafeCritical) - { - // Critical types require security checks - return true; - } - else if (IsGenericType) - { - // If any of the generic arguments to this type require a security check, then this type - // also requires one. - foreach (Type genericArgument in GetGenericArguments()) - { - if (genericArgument.NeedsReflectionSecurityCheck) - { - return true; - } - } - } - else if (IsArray || IsPointer) - { - return GetElementType().NeedsReflectionSecurityCheck; - } - - return false; - } - } - - // The behavior of UnderlyingSystemType varies from type to type. - // For IReflect objects: Return the underlying Type that represents the IReflect Object. - // For expando object: this is the (Object) IReflectInstance.GetType(). For Type object it is this. - // It could also return the baked type or the underlying enum type in RefEmit. See the comment in - // code:TypeBuilder.SetConstantValue. - public abstract Type UnderlyingSystemType - { - get; - } - - // Returns true of this class is a true subclass of c. Everything - // else returns false. If this class and c are the same class false is - // returned. - // - [Pure] - public virtual bool IsSubclassOf(Type c) - { - Type p = this; - if (p == c) - return false; - while (p != null) - { - if (p == c) - return true; - p = p.BaseType; - } - return false; - } - - // Returns true if the object passed is assignable to an instance of this class. - // Everything else returns false. - // - [Pure] - public virtual bool IsInstanceOfType(Object o) - { - if (o == null) - return false; - - // No need for transparent proxy casting check here - // because it never returns true for a non-rutnime type. - - return IsAssignableFrom(o.GetType()); - } - - // Returns true if an instance of Type c may be assigned - // to an instance of this class. Return false otherwise. - // - [Pure] - public virtual bool IsAssignableFrom(Type c) - { - if (c == null) - return false; - - if (this == c) - return true; - - // For backward-compatibility, we need to special case for the types - // whose UnderlyingSystemType are RuntimeType objects. - RuntimeType toType = this.UnderlyingSystemType as RuntimeType; - if (toType != null) - return toType.IsAssignableFrom(c); - - // If c is a subclass of this class, then c can be cast to this type. - if (c.IsSubclassOf(this)) - return true; - - if (this.IsInterface) - { - return c.ImplementInterface(this); - } - else if (IsGenericParameter) - { - Type[] constraints = GetGenericParameterConstraints(); - for (int i = 0; i < constraints.Length; i++) - if (!constraints[i].IsAssignableFrom(c)) - return false; - - return true; - } - - return false; - } - - // Base implementation that does only ==. - [Pure] - public virtual bool IsEquivalentTo(Type other) - { - return (this == other); - } - - internal bool ImplementInterface(Type ifaceType) - { - Contract.Requires(ifaceType != null); - Contract.Requires(ifaceType.IsInterface, "ifaceType must be an interface type"); - - Type t = this; - while (t != null) - { - Type[] interfaces = t.GetInterfaces(); - if (interfaces != null) - { - for (int i = 0; i < interfaces.Length; i++) - { - // Interfaces don't derive from other interfaces, they implement them. - // So instead of IsSubclassOf, we should use ImplementInterface instead. - if (interfaces[i] == ifaceType || - (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType))) - return true; - } - } - - t = t.BaseType; - } - - return false; - } - - // This is only ever called on RuntimeType objects. - internal string FormatTypeName() - { - return FormatTypeName(false); - } - - internal virtual string FormatTypeName(bool serialization) - { - throw new NotImplementedException(); - } - - // ToString - // Print the String Representation of the Type - public override String ToString() - { - // Why do we add the "Type: " prefix? RuntimeType.ToString() doesn't include it. - return "Type: " + Name; - } - - // This method will return an array of classes based upon the array of - // types. - public static Type[] GetTypeArray(Object[] args) - { - if (args == null) - throw new ArgumentNullException(nameof(args)); - Contract.EndContractBlock(); - Type[] cls = new Type[args.Length]; - for (int i = 0; i < cls.Length; i++) - { - if (args[i] == null) - throw new ArgumentNullException(); - cls[i] = args[i].GetType(); - } - return cls; - } - - [Pure] - public override bool Equals(Object o) - { - if (o == null) - return false; - - return Equals(o as Type); - } - - [Pure] - public virtual bool Equals(Type o) - { - if ((object)o == null) - return false; - - return (Object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType)); - } - - [Pure] - [MethodImplAttribute(MethodImplOptions.InternalCall)] - public static extern bool operator ==(Type left, Type right); + public virtual Type MakeArrayType() { throw new NotSupportedException(); } + public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); } + public virtual Type MakeByRefType() { throw new NotSupportedException(); } + public virtual Type MakeGenericType(params Type[] typeArguments) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } + public virtual Type MakePointerType() { throw new NotSupportedException(); } - [Pure] - [MethodImplAttribute(MethodImplOptions.InternalCall)] - public static extern bool operator !=(Type left, Type right); + public override string ToString() => "Type: " + Name; // Why do we add the "Type: " prefix? + public override bool Equals(object o) => o == null ? false : Equals(o as Type); public override int GetHashCode() { - Type SystemType = UnderlyingSystemType; - if (!Object.ReferenceEquals(SystemType, this)) - return SystemType.GetHashCode(); + Type systemType = UnderlyingSystemType; + if (!object.ReferenceEquals(systemType, this)) + return systemType.GetHashCode(); return base.GetHashCode(); } + public virtual bool Equals(Type o) => o == null ? false : object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType); + public static Type ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); } - // GetInterfaceMap - // This method will return an interface mapping for the interface - // requested. It will throw an argument exception if the Type doesn't - // implemenet the interface. - public virtual InterfaceMapping GetInterfaceMap(Type interfaceType) - { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); - } + public static readonly char Delimiter = '.'; + public static readonly Type[] EmptyTypes = Array.Empty<Type>(); + public static readonly object Missing = System.Reflection.Missing.Value; - // this method is required so Object.GetType is not made virtual by the compiler - public new Type GetType() - { - return base.GetType(); - } + public static readonly MemberFilter FilterAttribute = FilterAttributeImpl; + public static readonly MemberFilter FilterName = FilterNameImpl; + public static readonly MemberFilter FilterNameIgnoreCase = FilterNameIgnoreCaseImpl; - // private convenience data private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; } } diff --git a/src/mscorlib/src/System/__Filters.cs b/src/mscorlib/src/System/__Filters.cs deleted file mode 100644 index 32d1db3143..0000000000 --- a/src/mscorlib/src/System/__Filters.cs +++ /dev/null @@ -1,163 +0,0 @@ -// 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. - -// -// This class defines the delegate methods for the COM+ implemented filters. -// -// -// - -using System; -using System.Reflection; -using System.Globalization; - -namespace System -{ - [Serializable] - internal class __Filters - { - // Filters... - // The following are the built in filters defined for this class. These - // should really be defined as static methods. They are used in as delegates - // which currently doesn't support static methods. We will change this - // once the compiler supports delegates. - // - // Note that it is not possible to make this class static as suggested by - // the above comment anymore because of it got marked serializable. - - internal static readonly __Filters Instance = new __Filters(); - - // FilterAttribute - // This method will search for a member based upon the attribute passed in. - // filterCriteria -- an Int32 representing the attribute - internal virtual bool FilterAttribute(MemberInfo m, Object filterCriteria) - { - // Check that the criteria object is an Integer object - if (filterCriteria == null) - throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt")); - - switch (m.MemberType) - { - case MemberTypes.Constructor: - case MemberTypes.Method: - { - MethodAttributes criteria = 0; - try - { - int i = (int)filterCriteria; - criteria = (MethodAttributes)i; - } - catch - { - throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt")); - } - - - MethodAttributes attr; - if (m.MemberType == MemberTypes.Method) - attr = ((MethodInfo)m).Attributes; - else - attr = ((ConstructorInfo)m).Attributes; - - if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask)) - return false; - if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0) - return false; - if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0) - return false; - if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0) - return false; - if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0) - return false; - if (((criteria & MethodAttributes.SpecialName) != 0) && (attr & MethodAttributes.SpecialName) == 0) - return false; - return true; - } - case MemberTypes.Field: - { - FieldAttributes criteria = 0; - try - { - int i = (int)filterCriteria; - criteria = (FieldAttributes)i; - } - catch - { - throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt")); - } - - FieldAttributes attr = ((FieldInfo)m).Attributes; - if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask)) - return false; - if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0) - return false; - if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0) - return false; - if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0) - return false; - if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0) - return false; - if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0) - return false; - return true; - } - } - - return false; - } - // FilterName - // This method will filter based upon the name. A partial wildcard - // at the end of the string is supported. - // filterCriteria -- This is the string name - internal virtual bool FilterName(MemberInfo m, Object filterCriteria) - { - // Check that the criteria object is a String object - if (filterCriteria == null || !(filterCriteria is String)) - throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString")); - - // At the moment this fails if its done on a single line.... - String str = ((String)filterCriteria); - str = str.Trim(); - - String name = m.Name; - // Get the nested class name only, as opposed to the mangled one - if (m.MemberType == MemberTypes.NestedType) - name = name.Substring(name.LastIndexOf('+') + 1); - // Check to see if this is a prefix or exact match requirement - if (str.Length > 0 && str[str.Length - 1] == '*') - { - str = str.Substring(0, str.Length - 1); - return (name.StartsWith(str, StringComparison.Ordinal)); - } - - return (name.Equals(str)); - } - - // FilterIgnoreCase - // This delegate will do a name search but does it with the - // ignore case specified. - internal virtual bool FilterIgnoreCase(MemberInfo m, Object filterCriteria) - { - // Check that the criteria object is a String object - if (filterCriteria == null || !(filterCriteria is String)) - throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString")); - - String str = (String)filterCriteria; - str = str.Trim(); - - String name = m.Name; - // Get the nested class name only, as opposed to the mangled one - if (m.MemberType == MemberTypes.NestedType) - name = name.Substring(name.LastIndexOf('+') + 1); - // Check to see if this is a prefix or exact match requirement - if (str.Length > 0 && str[str.Length - 1] == '*') - { - str = str.Substring(0, str.Length - 1); - return (String.Compare(name, 0, str, 0, str.Length, StringComparison.OrdinalIgnoreCase) == 0); - } - - return (String.Compare(str, name, StringComparison.OrdinalIgnoreCase) == 0); - } - } -} |