public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaMethod method)
        {
            MetadataReader         reader       = method.MetadataReader;
            MethodDefinitionHandle methodHandle = method.Handle;
            MethodDefinition       methodDef    = reader.GetMethodDefinition(methodHandle);

            // Handle custom attributes on the method
            AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes());

            // Handle custom attributes on method parameters
            foreach (ParameterHandle parameterHandle in methodDef.GetParameters())
            {
                Parameter parameter = reader.GetParameter(parameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
            }

            // Handle custom attributes on generic method parameters
            foreach (GenericParameterHandle genericParameterHandle in methodDef.GetGenericParameters())
            {
                GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
            }

            // We don't model properties and events as separate entities within the compiler, so ensuring
            // we can generate custom attributes for the associated events and properties from here
            // is as good as any other place.
            //
            // As a performance optimization, we look for associated events and properties only
            // if the method is SpecialName. This is required for CLS compliance and compilers we
            // care about emit accessors like this.
            if ((methodDef.Attributes & MethodAttributes.SpecialName) != 0)
            {
                TypeDefinition declaringType = reader.GetTypeDefinition(methodDef.GetDeclaringType());

                foreach (PropertyDefinitionHandle propertyHandle in declaringType.GetProperties())
                {
                    PropertyDefinition property  = reader.GetPropertyDefinition(propertyHandle);
                    PropertyAccessors  accessors = property.GetAccessors();

                    if (accessors.Getter == methodHandle || accessors.Setter == methodHandle)
                    {
                        AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes());
                    }
                }

                foreach (EventDefinitionHandle eventHandle in declaringType.GetEvents())
                {
                    EventDefinition @event    = reader.GetEventDefinition(eventHandle);
                    EventAccessors  accessors = @event.GetAccessors();

                    if (accessors.Adder == methodHandle || accessors.Remover == methodHandle || accessors.Raiser == methodHandle)
                    {
                        AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes());
                    }
                }
            }
        }
예제 #2
0
 public static MethodDefinitionHandle GetAny(this EventAccessors accessors)
 {
     if (!accessors.Adder.IsNil)
     {
         return(accessors.Adder);
     }
     if (!accessors.Remover.IsNil)
     {
         return(accessors.Remover);
     }
     return(accessors.Raiser);
 }
예제 #3
0
        internal MetadataEvent(MetadataModule module, EventDefinitionHandle handle)
        {
            Debug.Assert(module != null);
            Debug.Assert(!handle.IsNil);
            this.module = module;
            this.handle = handle;

            var metadata = module.metadata;
            var ev       = metadata.GetEventDefinition(handle);

            accessors = ev.GetAccessors();
            name      = metadata.GetString(ev.Name);
        }
예제 #4
0
        protected sealed override MethodInfo GetEventMethod(EventMethodSemantics whichMethod)
        {
            EventAccessors         eventAccessors = _event.GetAccessors();
            MethodDefinitionHandle methodHandle;

            switch (whichMethod)
            {
            case EventMethodSemantics.Add:
                methodHandle = eventAccessors.Adder;
                break;

            case EventMethodSemantics.Remove:
                methodHandle = eventAccessors.Remover;
                break;

            case EventMethodSemantics.Fire:
                methodHandle = eventAccessors.Raiser;
                break;

            default:
                return(null);
            }

            /*
             * This logic is part of the corresponding PropertyInfo code.. should it be here?
             * bool inherited = !_reflectedType.Equals(ContextTypeInfo);
             * if (inherited)
             * {
             *  MethodAttributes flags = _reader.GetMethodDefinition(methodHandle).Attributes;
             *  if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private)
             *      return null;
             * }
             */

            return(RuntimeNamedMethodInfo <EcmaFormatMethodCommon> .GetRuntimeNamedMethodInfo(new EcmaFormatMethodCommon(methodHandle, _definingTypeInfo, ContextTypeInfo), ReflectedTypeInfo));
        }
        private Mapping <EventDefinitionHandle> MapEventDefinitionImpl(EventDefinitionHandle handle)
        {
            EventDefinition eventDefinition = _sourceMetadata.GetEventDefinition(handle);
            EventAccessors  accessors       = eventDefinition.GetAccessors();

            // events always have an adder method, so use that to find the declaring type
            MethodDefinition adderMethodDefinition = _sourceMetadata.GetMethodDefinition(accessors.Adder);
            Mapping <TypeDefinitionHandle> declaringTypeMapping = MapTypeDefinition(adderMethodDefinition.GetDeclaringType());

            if (declaringTypeMapping.Target.IsNil)
            {
                return(new Mapping <EventDefinitionHandle>());
            }

            // Make sure each of the accessors maps successfully. Only the raiser is optional.
            Mapping <MethodDefinitionHandle> adderMethodDefinitionMapping = MapMethodDefinition(accessors.Adder);

            if (adderMethodDefinitionMapping.Target.IsNil)
            {
                return(new Mapping <EventDefinitionHandle>());
            }

            Mapping <MethodDefinitionHandle> removerMethodDefinitionMapping = MapMethodDefinition(accessors.Remover);

            if (removerMethodDefinitionMapping.Target.IsNil)
            {
                return(new Mapping <EventDefinitionHandle>());
            }

            Mapping <MethodDefinitionHandle> raiserMethodDefinitionMapping = default(Mapping <MethodDefinitionHandle>);

            if (!accessors.Raiser.IsNil)
            {
                raiserMethodDefinitionMapping = MapMethodDefinition(accessors.Raiser);
                if (raiserMethodDefinitionMapping.Target.IsNil)
                {
                    return(new Mapping <EventDefinitionHandle>());
                }
            }

            // locate the target event by name
            string eventName = _sourceMetadata.GetString(eventDefinition.Name);
            EventDefinitionHandle targetEventDefinitionHandle = default(EventDefinitionHandle);
            EventDefinition       targetEventDefinition       = default(EventDefinition);

            foreach (var targetHandle in _targetMetadata.EventDefinitions)
            {
                targetEventDefinition = _targetMetadata.GetEventDefinition(targetHandle);
                MethodDefinition targetAdderMethodDefinition = _targetMetadata.GetMethodDefinition(targetEventDefinition.GetAccessors().Adder);
                if (targetAdderMethodDefinition.GetDeclaringType() != declaringTypeMapping.Target)
                {
                    continue;
                }

                if (!_targetMetadata.StringComparer.Equals(targetEventDefinition.Name, eventName))
                {
                    continue;
                }

                targetEventDefinitionHandle = targetHandle;
                break;
            }

            if (targetEventDefinitionHandle.IsNil)
            {
                return(new Mapping <EventDefinitionHandle>());
            }

            EventAccessors targetAccessors = targetEventDefinition.GetAccessors();

            if (targetAccessors.Adder != adderMethodDefinitionMapping.Target)
            {
                return(new Mapping <EventDefinitionHandle>());
            }

            if (targetAccessors.Remover != removerMethodDefinitionMapping.Target)
            {
                return(new Mapping <EventDefinitionHandle>());
            }

            if (!accessors.Raiser.IsNil)
            {
                if (targetAccessors.Raiser != raiserMethodDefinitionMapping.Target)
                {
                    return(new Mapping <EventDefinitionHandle>());
                }
            }

            return(new Mapping <EventDefinitionHandle>(targetEventDefinitionHandle));
        }