Пример #1
0
        public void GetAccessors(out MrMethod adder, out MrMethod remover, bool publicishOnly = true)
        {
            var eventAccessors = Definition.GetAccessors();

            adder   = MrMethod.TryGetMethod(eventAccessors.Adder, DeclaringType, publicishOnly);
            remover = MrMethod.TryGetMethod(eventAccessors.Remover, DeclaringType, publicishOnly);
        }
        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());
                    }
                }
            }
        }
Пример #3
0
        public override AstNode Visit(EventDefinition node)
        {
            // Add the parent static flag.
            if (currentContainer.IsStatic())
            {
                MemberFlags oldInstance = node.GetFlags() & MemberFlags.InstanceMask;
                if (oldInstance == MemberFlags.Static || oldInstance == MemberFlags.Instanced)
                {
                    MemberFlags flags = node.GetFlags() & ~MemberFlags.InstanceMask;
                    node.SetFlags(flags | MemberFlags.Static);
                }
                else
                {
                    Error(node, "static class member cannot {0}.", oldInstance.ToString().ToLower());
                }
            }

            // Link the accessors.
            AstNode acc = node.GetAccessors();

            while (acc != null)
            {
                EventAccessorDefinition eacc = (EventAccessorDefinition)acc;
                string accName = eacc.GetName();
                if (accName == "add")
                {
                    if (node.AddAccessor != null)
                    {
                        Error(node, "an event only can have one add accessor.");
                    }
                    node.AddAccessor = eacc;
                }
                else if (accName == "remove")
                {
                    if (node.RemoveAccessor != null)
                    {
                        Error(node, "an event only can have one remove accessor.");
                    }
                    node.RemoveAccessor = eacc;
                }
                else
                {
                    Error(acc, "invalid event accessor name.");
                }

                acc = acc.GetNext();
            }

            return(node);
        }
Пример #4
0
 internal static CilEventDefinition Create(EventDefinition eventDefinition, int token, ref CilReaders readers, CilTypeDefinition declaringType)
 {
     CilEventDefinition eventDef = new CilEventDefinition();
     eventDef._eventDefinition = eventDefinition;
     eventDef._readers = readers;
     eventDef._typeDefinition = declaringType;
     eventDef._accessors = eventDefinition.GetAccessors();
     eventDef._isAdderInitialized = false;
     eventDef._isRemoverInitialized = false;
     eventDef._isRaiserInitialized = false;
     eventDef._isEntityInitialized = false;
     eventDef._token = token;
     return eventDef;
 }
Пример #5
0
        internal static CilEventDefinition Create(EventDefinition eventDefinition, int token, ref CilReaders readers, CilTypeDefinition declaringType)
        {
            CilEventDefinition eventDef = new CilEventDefinition();

            eventDef._eventDefinition      = eventDefinition;
            eventDef._readers              = readers;
            eventDef._typeDefinition       = declaringType;
            eventDef._accessors            = eventDefinition.GetAccessors();
            eventDef._isAdderInitialized   = false;
            eventDef._isRemoverInitialized = false;
            eventDef._isRaiserInitialized  = false;
            eventDef._isEntityInitialized  = false;
            eventDef._token = token;
            return(eventDef);
        }
Пример #6
0
        public sealed override MethodInfo[] GetOtherMethods(bool nonPublic)
        {
            MetadataReader reader = Reader;
            ImmutableArray <MethodDefinitionHandle> others = EventDefinition.GetAccessors().Others;
            int count = others.Length;
            List <MethodInfo> results = new List <MethodInfo>(capacity: count);

            for (int i = 0; i < count; i++)
            {
                MethodDefinition def = others[i].GetMethodDefinition(reader);
                if (nonPublic || (def.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public)
                {
                    MethodInfo methodInfo = others[i].ToMethod(GetRoDeclaringType(), GetRoDeclaringType());
                    results.Add(methodInfo);
                }
            }
            return(results.ToArray());
        }
Пример #7
0
 protected sealed override RoMethod?ComputeEventRaiseMethod() => EventDefinition.GetAccessors().Raiser.ToMethodOrNull(GetRoDeclaringType(), ReflectedType);
        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));
        }