summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/MethodBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Reflection/MethodBase.cs')
-rw-r--r--src/mscorlib/src/System/Reflection/MethodBase.cs403
1 files changed, 403 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Reflection/MethodBase.cs b/src/mscorlib/src/System/Reflection/MethodBase.cs
new file mode 100644
index 0000000000..6b3e2a301b
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/MethodBase.cs
@@ -0,0 +1,403 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+//
+
+namespace System.Reflection
+{
+ using System;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+ using System.Security.Permissions;
+ using System.Text;
+ using System.Threading;
+
+ //
+ // Invocation cached flags. Those are used in unmanaged code as well
+ // so be careful if you change them
+ //
+ [Flags]
+ internal enum INVOCATION_FLAGS : uint
+ {
+ INVOCATION_FLAGS_UNKNOWN = 0x00000000,
+ INVOCATION_FLAGS_INITIALIZED = 0x00000001,
+ // it's used for both method and field to signify that no access is allowed
+ INVOCATION_FLAGS_NO_INVOKE = 0x00000002,
+ INVOCATION_FLAGS_NEED_SECURITY = 0x00000004,
+ // Set for static ctors and ctors on abstract types, which
+ // can be invoked only if the "this" object is provided (even if it's null).
+ INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008,
+ // because field and method are different we can reuse the same bits
+ // method
+ INVOCATION_FLAGS_IS_CTOR = 0x00000010,
+ INVOCATION_FLAGS_RISKY_METHOD = 0x00000020,
+ INVOCATION_FLAGS_NON_W8P_FX_API = 0x00000040,
+ INVOCATION_FLAGS_IS_DELEGATE_CTOR = 0x00000080,
+ INVOCATION_FLAGS_CONTAINS_STACK_POINTERS = 0x00000100,
+ // field
+ INVOCATION_FLAGS_SPECIAL_FIELD = 0x00000010,
+ INVOCATION_FLAGS_FIELD_SPECIAL_CAST = 0x00000020,
+
+ // temporary flag used for flagging invocation of method vs ctor
+ // this flag never appears on the instance m_invocationFlag and is simply
+ // passed down from within ConstructorInfo.Invoke()
+ INVOCATION_FLAGS_CONSTRUCTOR_INVOKE = 0x10000000,
+ }
+
+ [Serializable]
+ [ClassInterface(ClassInterfaceType.None)]
+ [ComDefaultInterface(typeof(_MethodBase))]
+#pragma warning disable 618
+ [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
+#pragma warning restore 618
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public abstract class MethodBase : MemberInfo, _MethodBase
+ {
+ #region Static Members
+ public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle)
+ {
+ if (handle.IsNullHandle())
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
+
+ MethodBase m = RuntimeType.GetMethodBase(handle.GetMethodInfo());
+
+ Type declaringType = m.DeclaringType;
+ if (declaringType != null && declaringType.IsGenericType)
+ throw new ArgumentException(String.Format(
+ CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MethodDeclaringTypeGeneric"),
+ m, declaringType.GetGenericTypeDefinition()));
+
+ return m;
+ }
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType)
+ {
+ if (handle.IsNullHandle())
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
+
+ return RuntimeType.GetMethodBase(declaringType.GetRuntimeType(), handle.GetMethodInfo());
+ }
+
+ [System.Security.DynamicSecurityMethod] // Specify DynamicSecurityMethod attribute to prevent inlining of the caller.
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static MethodBase GetCurrentMethod()
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeMethodInfo.InternalGetCurrentMethod(ref stackMark);
+ }
+ #endregion
+
+ #region Constructor
+ protected MethodBase() { }
+ #endregion
+
+#if !FEATURE_CORECLR
+ public static bool operator ==(MethodBase left, MethodBase right)
+ {
+ if (ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ MethodInfo method1, method2;
+ ConstructorInfo constructor1, constructor2;
+
+ if ((method1 = left as MethodInfo) != null && (method2 = right as MethodInfo) != null)
+ return method1 == method2;
+ else if ((constructor1 = left as ConstructorInfo) != null && (constructor2 = right as ConstructorInfo) != null)
+ return constructor1 == constructor2;
+
+ return false;
+ }
+
+ public static bool operator !=(MethodBase left, MethodBase right)
+ {
+ return !(left == right);
+ }
+#endif // !FEATURE_CORECLR
+
+ public override bool Equals(object obj)
+ {
+ return base.Equals(obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ #region Internal Members
+ // used by EE
+ [System.Security.SecurityCritical]
+ private IntPtr GetMethodDesc() { return MethodHandle.Value; }
+
+#if FEATURE_APPX
+
+ // The C# dynamic and VB late bound binders need to call this API. Since we don't have time to make this
+ // public in Dev11, the C# and VB binders currently call this through a delegate.
+ // When we make this API public (hopefully) in Dev12 we need to change the C# and VB binders to call this
+ // probably statically. The code is located in:
+ // C#: ndp\fx\src\CSharp\Microsoft\CSharp\SymbolTable.cs - Microsoft.CSharp.RuntimeBinder.SymbolTable..cctor
+ // VB: vb\runtime\msvbalib\helpers\Symbols.vb - Microsoft.VisualBasic.CompilerServices.Symbols..cctor
+ internal virtual bool IsDynamicallyInvokable
+ {
+ get
+ {
+ return true;
+ }
+ }
+#endif
+ #endregion
+
+ #region Public Abstract\Virtual Members
+ internal virtual ParameterInfo[] GetParametersNoCopy() { return GetParameters (); }
+
+ [System.Diagnostics.Contracts.Pure]
+ public abstract ParameterInfo[] GetParameters();
+
+ public virtual MethodImplAttributes MethodImplementationFlags
+ {
+ get
+ {
+ return GetMethodImplementationFlags();
+ }
+ }
+
+ public abstract MethodImplAttributes GetMethodImplementationFlags();
+
+ public abstract RuntimeMethodHandle MethodHandle { get; }
+
+ public abstract MethodAttributes Attributes { get; }
+
+ public abstract Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
+
+ public virtual CallingConventions CallingConvention { get { return CallingConventions.Standard; } }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public virtual Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
+
+ public virtual bool IsGenericMethodDefinition { get { return false; } }
+
+ public virtual bool ContainsGenericParameters { get { return false; } }
+
+ public virtual bool IsGenericMethod { get { return false; } }
+
+ public virtual bool IsSecurityCritical { get { throw new NotImplementedException(); } }
+
+ public virtual bool IsSecuritySafeCritical { get { throw new NotImplementedException(); } }
+
+ public virtual bool IsSecurityTransparent { get { throw new NotImplementedException(); } }
+
+ #endregion
+
+ #region Public Members
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public Object Invoke(Object obj, Object[] parameters)
+ {
+ // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
+ // But to maintain backward compatibility we can't switch to calling an
+ // internal overload that takes a stack mark.
+ // Fortunately the stack walker skips all the reflection invocation frames including this one.
+ // So this method will never be returned by the stack walker as the caller.
+ // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
+ return Invoke(obj, BindingFlags.Default, null, parameters, null);
+ }
+
+ public bool IsPublic { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } }
+
+ public bool IsPrivate { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } }
+
+ public bool IsFamily { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } }
+
+ public bool IsAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } }
+
+ public bool IsFamilyAndAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } }
+
+ public bool IsFamilyOrAssembly { get {return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } }
+
+ public bool IsStatic { get { return(Attributes & MethodAttributes.Static) != 0; } }
+
+ public bool IsFinal { get { return(Attributes & MethodAttributes.Final) != 0; }
+ }
+ public bool IsVirtual { get { return(Attributes & MethodAttributes.Virtual) != 0; }
+ }
+ public bool IsHideBySig { get { return(Attributes & MethodAttributes.HideBySig) != 0; } }
+
+ public bool IsAbstract { get { return(Attributes & MethodAttributes.Abstract) != 0; } }
+
+ public bool IsSpecialName { get { return(Attributes & MethodAttributes.SpecialName) != 0; } }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public bool IsConstructor
+ {
+ get
+ {
+ // To be backward compatible we only return true for instance RTSpecialName ctors.
+ return (this is ConstructorInfo &&
+ !IsStatic &&
+ ((Attributes & MethodAttributes.RTSpecialName) == MethodAttributes.RTSpecialName));
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+#pragma warning disable 618
+ [ReflectionPermissionAttribute(SecurityAction.Demand, Flags=ReflectionPermissionFlag.MemberAccess)]
+#pragma warning restore 618
+ public virtual MethodBody GetMethodBody()
+ {
+ throw new InvalidOperationException();
+ }
+ #endregion
+
+ #region Internal Methods
+ // helper method to construct the string representation of the parameter list
+
+ internal static string ConstructParameters(Type[] parameterTypes, CallingConventions callingConvention, bool serialization)
+ {
+ StringBuilder sbParamList = new StringBuilder();
+ string comma = "";
+
+ for (int i = 0; i < parameterTypes.Length; i++)
+ {
+ Type t = parameterTypes[i];
+
+ sbParamList.Append(comma);
+
+ string typeName = t.FormatTypeName(serialization);
+
+ // Legacy: Why use "ByRef" for by ref parameters? What language is this?
+ // VB uses "ByRef" but it should precede (not follow) the parameter name.
+ // Why don't we just use "&"?
+ if (t.IsByRef && !serialization)
+ {
+ sbParamList.Append(typeName.TrimEnd(new char[] { '&' }));
+ sbParamList.Append(" ByRef");
+ }
+ else
+ {
+ sbParamList.Append(typeName);
+ }
+
+ comma = ", ";
+ }
+
+ if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
+ {
+ sbParamList.Append(comma);
+ sbParamList.Append("...");
+ }
+
+ return sbParamList.ToString();
+ }
+
+ internal string FullName
+ {
+ get
+ {
+ return String.Format("{0}.{1}", DeclaringType.FullName, FormatNameAndSig());
+ }
+ }
+ internal string FormatNameAndSig()
+ {
+ return FormatNameAndSig(false);
+ }
+
+ internal virtual string FormatNameAndSig(bool serialization)
+ {
+ // Serialization uses ToString to resolve MethodInfo overloads.
+ StringBuilder sbName = new StringBuilder(Name);
+
+ sbName.Append("(");
+ sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
+ sbName.Append(")");
+
+ return sbName.ToString();
+ }
+
+ internal virtual Type[] GetParameterTypes()
+ {
+ ParameterInfo[] paramInfo = GetParametersNoCopy();
+
+ Type[] parameterTypes = new Type[paramInfo.Length];
+ for (int i = 0; i < paramInfo.Length; i++)
+ parameterTypes[i] = paramInfo[i].ParameterType;
+
+ return parameterTypes;
+ }
+
+ [System.Security.SecuritySafeCritical]
+ internal Object[] CheckArguments(Object[] parameters, Binder binder,
+ BindingFlags invokeAttr, CultureInfo culture, Signature sig)
+ {
+ // copy the arguments in a different array so we detach from any user changes
+ Object[] copyOfParameters = new Object[parameters.Length];
+
+ ParameterInfo[] p = null;
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ Object arg = parameters[i];
+ RuntimeType argRT = sig.Arguments[i];
+
+ if (arg == Type.Missing)
+ {
+ if (p == null)
+ p = GetParametersNoCopy();
+ if (p[i].DefaultValue == System.DBNull.Value)
+ throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),"parameters");
+ arg = p[i].DefaultValue;
+ }
+ copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr);
+ }
+
+ return copyOfParameters;
+ }
+ #endregion
+
+ #region _MethodBase Implementation
+#if !FEATURE_CORECLR
+ Type _MethodBase.GetType() { return base.GetType(); }
+ bool _MethodBase.IsPublic { get { return IsPublic; } }
+ bool _MethodBase.IsPrivate { get { return IsPrivate; } }
+ bool _MethodBase.IsFamily { get { return IsFamily; } }
+ bool _MethodBase.IsAssembly { get { return IsAssembly; } }
+ bool _MethodBase.IsFamilyAndAssembly { get { return IsFamilyAndAssembly; } }
+ bool _MethodBase.IsFamilyOrAssembly { get { return IsFamilyOrAssembly; } }
+ bool _MethodBase.IsStatic { get { return IsStatic; } }
+ bool _MethodBase.IsFinal { get { return IsFinal; } }
+ bool _MethodBase.IsVirtual { get { return IsVirtual; } }
+ bool _MethodBase.IsHideBySig { get { return IsHideBySig; } }
+ bool _MethodBase.IsAbstract { get { return IsAbstract; } }
+ bool _MethodBase.IsSpecialName { get { return IsSpecialName; } }
+ bool _MethodBase.IsConstructor { get { return IsConstructor; } }
+
+ void _MethodBase.GetTypeInfoCount(out uint pcTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _MethodBase.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _MethodBase.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+ {
+ throw new NotImplementedException();
+ }
+
+ // If you implement this method, make sure to include _MethodBase.Invoke in VM\DangerousAPIs.h and
+ // include _MethodBase in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
+ void _MethodBase.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+ {
+ throw new NotImplementedException();
+ }
+#endif
+ #endregion
+ }
+
+}