private static EventDefinition CreateDummyEventToType(TypeDefinition dummyType, ITypeDefOrRef eventHandlerTypeRef, string name) { var eventHandlerTypeSig = eventHandlerTypeRef.ToTypeSignature(); // Define new event. var @event = new EventDefinition(name, 0, eventHandlerTypeRef); // Create signature for add/remove methods. var signature = MethodSignature.CreateStatic( eventHandlerTypeRef.Module.CorLibTypeFactory.Void, eventHandlerTypeRef.Module.CorLibTypeFactory.Object, eventHandlerTypeSig); var methodAttributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define add. var addMethod = new MethodDefinition($"add_{@event.Name}", methodAttributes, signature); addMethod.CilMethodBody = new CilMethodBody(addMethod) { Instructions = { new CilInstruction(CilOpCodes.Ret) } }; // Define remove. var removeMethod = new MethodDefinition($"remove_{@event.Name}", methodAttributes, signature); removeMethod.CilMethodBody = new CilMethodBody(removeMethod) { Instructions = { new CilInstruction(CilOpCodes.Ret) } }; // Add members. dummyType.Methods.Add(addMethod); dummyType.Methods.Add(removeMethod); @event.Semantics.Add(new MethodSemantics(addMethod, MethodSemanticsAttributes.AddOn)); @event.Semantics.Add(new MethodSemantics(removeMethod, MethodSemanticsAttributes.RemoveOn)); return(@event); }
public IList <ITypeDescriptor> GetTypeHierarchy(ITypeDescriptor type) { var result = new List <ITypeDescriptor>(); TypeSignature typeSig; switch (type) { // The base type of an array type signature is System.Array, so it needs a special case. // Get the type hierarchy of System.Array and then append the original array type sig. case ArrayTypeSignature _: case SzArrayTypeSignature _: result.AddRange(GetTypeHierarchy(_arrayType)); result.Add(type); return(result); case ByReferenceTypeSignature byRef: result.AddRange(GetTypeHierarchy(byRef.BaseType)); // result.Add(byRef); return(result); // Type specification's Resolve method resolves the underlying element type. // We therefore need a special case here, to get the type hierarchy of the embedded signature first. case TypeSpecification typeSpec: result.AddRange(GetTypeHierarchy(typeSpec.Signature)); result.Add(typeSpec); return(result); case GenericParameterSignature genericParam: // TODO: Resolve to actual generic parameter type. result.Add(_objectType); return(result); // No type means no hierarchy. case null: return(Array.Empty <ITypeDescriptor>()); default: typeSig = type.ToTypeSignature(); break; } var genericContext = new GenericContext(null, null); while (typeSig != null) { if (typeSig is GenericInstanceTypeSignature genericInstance) { genericContext = new GenericContext(genericInstance, null); } result.Add(typeSig); var typeDef = typeSig.ToTypeDefOrRef().Resolve(); if (typeDef is null) { throw new ArgumentException( $"Could not resolve type {typeSig.FullName} in {typeSig.Scope.GetAssembly()}."); } if (typeDef.IsEnum) { typeSig = typeDef.GetEnumUnderlyingType(); } else if (typeDef.IsInterface && typeDef.BaseType is null) { typeSig = _objectType.ToTypeSignature(); } else { typeSig = typeDef.BaseType?.ToTypeSignature().InstantiateGenericTypes(genericContext); } } result.Reverse(); return(result); }