public MethodMetadataICodeElementAdapter(Method method, TypeDefinition typeDefinition, IList<TypeDescriptor> genericTypes, MetadataReader reader) : base(typeDefinition, genericTypes, reader) { if (method == null) { throw new ArgumentNullException("method"); } this.Method = method; }
public Property GetPropertyProperties(int token) { // The Property's name will be stored in this array. The 1024 is a "magical number", seems like a type's name can be maximum this long. The corhlpr.h also defines a suspicious constant like this: #define MAX_CLASSNAME_LENGTH 1024 var propertyName = new char[1024]; var typeDefToken = 0; // Number of how many characters were filled in the typeName array. var nameLength = 0; // A pointer to the binary metadata signature of the property. var sigBlob = new IntPtr(0); var sigBlobLength = 0; // Property's flags. var propertyFlags = 0; // A flag that marks a ValueType var cplusTypeFlag = 0; // A constant string value returned by this member. var defaultValue = new IntPtr(0); var defaultValueLength = 0; // method token AddOn var methodTokenGetter = 0; // method token RemoveOn var methodTokenSetter = 0; var otherMethodTokens = new int[1024]; var otherMethodTokensCount = 0; // Get the Property's properties. var hresult = this.import.GetPropertyProps( token, ref typeDefToken, propertyName, propertyName.Length, ref nameLength, ref propertyFlags, ref sigBlob, ref sigBlobLength, ref cplusTypeFlag, ref defaultValue, ref defaultValueLength, ref methodTokenSetter, ref methodTokenGetter, otherMethodTokens, 1024, ref otherMethodTokensCount); if (hresult != 0) { Marshal.ThrowExceptionForHR(hresult); } // supress names "" & "\0"; if (nameLength <= 1) { // return null for this, we do not need to know about empty base return null; } // Get the Property's name. var fullTypeName = new string(propertyName, 0, nameLength - 1); var sigBlobBytes = new byte[sigBlobLength]; for (var byteIndex = 0; byteIndex < sigBlobLength; byteIndex++) { sigBlobBytes[byteIndex] = Marshal.ReadByte(sigBlob, byteIndex); } var defaultValueBytes = new byte[defaultValueLength]; for (var byteIndex = 0; byteIndex < defaultValueLength; byteIndex++) { defaultValueBytes[byteIndex] = Marshal.ReadByte(defaultValue, byteIndex); } var otherMethods = new Method[otherMethodTokensCount]; for (var otherMethodTokenIndex = 0; otherMethodTokenIndex < otherMethodTokensCount; otherMethodTokenIndex++) { otherMethods[otherMethodTokenIndex] = this.GetMethodProperties(otherMethodTokens[otherMethodTokenIndex]); } var propertyProperties = new Property { Token = token, FullName = fullTypeName, Flags = (CorPropertyAttr)propertyFlags, CPlusTypeFlag = (CorElementType)cplusTypeFlag, DefaultValue = defaultValueBytes, SignatureBlob = sigBlobBytes, Getter = this.GetMethodProperties(methodTokenGetter), Setter = methodTokenSetter.IsNotEmpty(CorTokenType.MethodDef) ? this.GetMethodProperties(methodTokenSetter) : null, Other = otherMethods }; propertyProperties.ReadSignature(this); return propertyProperties; }
public Method GetMethodProperties(int token) { object metadataObject = null; if (this.metadataObjectsCache.TryGetValue(token, out metadataObject)) { return (Method)metadataObject; } // The Method's name will be stored in this array. The 1024 is a "magical number", seems like a type's name can be maximum this long. The corhlpr.h also defines a suspicious constant like this: #define MAX_CLASSNAME_LENGTH 1024 var methodName = new char[1024]; var typeDefToken = 0; // Number of how many characters were filled in the typeName array. var nameLength = 0; // Method's flags. var attr = 0; // A pointer to the binary metadata signature of the Method. var sigBlob = new IntPtr(0); var sigBlobLength = 0; // A pointer to the relative virtual address of the Method. var codeRva = 0; var methodImplementationFlags = 0; // Get the Method's properties. var hresult = this.import.GetMethodProps( token, ref typeDefToken, methodName, methodName.Length, ref nameLength, ref attr, ref sigBlob, ref sigBlobLength, ref codeRva, ref methodImplementationFlags); if (hresult != 0) { Marshal.ThrowExceptionForHR(hresult); } // supress names "" & "\0"; if (nameLength <= 1) { // return null for this, we do not need to know about empty base return null; } // Get the Method's name. var fullTypeName = new string(methodName, 0, nameLength - 1); var sigBlobBytes = new byte[sigBlobLength]; for (var byteIndex = 0; byteIndex < sigBlobLength; byteIndex++) { sigBlobBytes[byteIndex] = Marshal.ReadByte(sigBlob, byteIndex); } var methodProperties = new Method { Token = token, FullName = fullTypeName, Flags = (CorMethodAttr)attr, SignatureBlob = sigBlobBytes, CodeRva = codeRva, ImplementationFlags = (CorMethodImpl)methodImplementationFlags }; // read method params methodProperties.Params = this.EnumerateParams(methodProperties).ToArray(); methodProperties.ReadSignature(this); return methodProperties; }
public Event GetEventProperties(int token) { // The Event's name will be stored in this array. The 1024 is a "magical number", seems like a type's name can be maximum this long. The corhlpr.h also defines a suspicious constant like this: #define MAX_CLASSNAME_LENGTH 1024 var eventName = new char[1024]; var typeDefToken = 0; // Number of how many characters were filled in the typeName array. var nameLength = 0; // Event's flags. var eventFlags = 0; // A pointer to a TypeRef or TypeDef metadata token representing the Delegate type of the event. var eventTypeToken = 0; // method token AddOn var methodTokenAddOn = 0; // method token RemoveOn var methodTokenRemoveOn = 0; // method token Fire var methodTokenFire = 0; var otherMethodTokens = new int[1024]; var otherMethodTokensCount = 0; // Get the Event's properties. var hresult = this.import.GetEventProps( token, ref typeDefToken, eventName, eventName.Length, ref nameLength, ref eventFlags, ref eventTypeToken, ref methodTokenAddOn, ref methodTokenRemoveOn, ref methodTokenFire, otherMethodTokens, 1024, ref otherMethodTokensCount); if (hresult != 0) { Marshal.ThrowExceptionForHR(hresult); } // supress names "" & "\0"; if (nameLength <= 1) { // return null for this, we do not need to know about empty base return null; } // Get the Event's name. var fullTypeName = new string(eventName, 0, nameLength - 1); var otherMethods = new Method[otherMethodTokensCount]; for (var otherMethodTokenIndex = 0; otherMethodTokenIndex < otherMethodTokensCount; otherMethodTokenIndex++) { otherMethods[otherMethodTokenIndex] = this.GetMethodProperties(otherMethodTokens[otherMethodTokenIndex]); } var eventProperties = new Event { Token = token, FullName = fullTypeName, Flags = (CorEventAttr)eventFlags, Type = eventTypeToken.Is(CorTokenType.TypeDef) ? (object)this.GetTypeDefinitionProperties(eventTypeToken) : (object)this.GetTypeReferenceProperties(eventTypeToken), AddOn = this.GetMethodProperties(methodTokenAddOn), RemoveOn = this.GetMethodProperties(methodTokenRemoveOn), Fire = methodTokenFire.IsNotEmpty(CorTokenType.MethodDef) ? this.GetMethodProperties(methodTokenFire) : null, Other = otherMethods }; return eventProperties; }
/// <summary> /// Enumerates ParamDef tokens representing Params of the specified type. /// /// To enumerate inherited Params, the caller must explicitly walk the inheritance chain. /// </summary> /// <param name="method"> A ReturnTypeDefinition representing the type whose Params are to be enumerated</param> /// <returns>the enumerator</returns> public IEnumerable<Param> EnumerateParams(Method method) { // Handle of the enumeration. var enumHandle = 0; // We will read maximum 10 Params at once which will be stored in this array. var @params = new int[10]; // Number of read Params. var count = 0; var hresult = this.import.EnumParams(ref enumHandle, method.Token, @params, @params.Length, ref count); if (hresult != 0) { Marshal.ThrowExceptionForHR(hresult); } // Continue reading Params' while the Params array contains any new Param. while (count > 0) { for (uint paramsIndex = 0; paramsIndex < count; paramsIndex++) { yield return this.GetParamProperties(@params[paramsIndex]); } hresult = this.import.EnumParams(ref enumHandle, method.Token, @params, @params.Length, ref count); if (hresult != 0) { Marshal.ThrowExceptionForHR(hresult); } } this.import.CloseEnum(enumHandle); }