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);
        }
Exemplo n.º 2
0
        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);
        }