EventDeclaration TransformAutomaticEvents(CustomEventDeclaration ev)
        {
            if (!ev.PrivateImplementationType.IsNull)
            {
                return(null);
            }
            if (!ev.Modifiers.HasFlag(Modifiers.Abstract))
            {
                if (!CheckAutomaticEventV4(ev) && !CheckAutomaticEventV2(ev) && !CheckAutomaticEventV4MCS(ev))
                {
                    return(null);
                }
            }
            RemoveCompilerGeneratedAttribute(ev.AddAccessor.Attributes, attributeTypesToRemoveFromAutoEvents);
            EventDeclaration ed = new EventDeclaration();

            ev.Attributes.MoveTo(ed.Attributes);
            foreach (var attr in ev.AddAccessor.Attributes)
            {
                attr.AttributeTarget = "method";
                ed.Attributes.Add(attr.Detach());
            }
            ed.ReturnType = ev.ReturnType.Detach();
            ed.Modifiers  = ev.Modifiers;
            ed.Variables.Add(new VariableInitializer(ev.Name));
            ed.CopyAnnotationsFrom(ev);

            IEvent eventDef = ev.GetSymbol() as IEvent;

            if (eventDef != null)
            {
                IField field = eventDef.DeclaringType.GetFields(f => f.Name == ev.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
                if (field != null)
                {
                    ed.AddAnnotation(field);
                    var attributes = field.GetAttributes()
                                     .Where(a => !attributeTypesToRemoveFromAutoEvents.Contains(a.AttributeType.FullName))
                                     .Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray();
                    if (attributes.Length > 0)
                    {
                        var section = new AttributeSection {
                            AttributeTarget = "field"
                        };
                        section.Attributes.AddRange(attributes);
                        ed.Attributes.Add(section);
                    }
                }
            }

            ev.ReplaceWith(ed);
            return(ed);
        }
        EventDeclaration TransformAutomaticEvents(CustomEventDeclaration ev)
        {
            Match m1 = automaticEventPatternV4.Match(ev.AddAccessor);

            if (!CheckAutomaticEventV4Match(m1, ev, true))
            {
                return(null);
            }
            Match m2 = automaticEventPatternV4.Match(ev.RemoveAccessor);

            if (!CheckAutomaticEventV4Match(m2, ev, false))
            {
                return(null);
            }
            EventDeclaration ed = new EventDeclaration();

            ev.Attributes.MoveTo(ed.Attributes);
            ed.ReturnType = ev.ReturnType.Detach();
            ed.Modifiers  = ev.Modifiers;
            ed.Variables.Add(new VariableInitializer(ev.Name));
            ed.CopyAnnotationsFrom(ev);

            EventDefinition eventDef = ev.Annotation <EventDefinition>();

            if (eventDef != null)
            {
                FieldDefinition field = eventDef.DeclaringType.Fields.FirstOrDefault(f => f.Name == ev.Name);
                if (field != null)
                {
                    ed.AddAnnotation(field);
                    AstBuilder.ConvertAttributes(ed, field, AttributeTarget.Field);
                }
            }

            ev.ReplaceWith(ed);
            return(ed);
        }
Beispiel #3
0
        public void Run(AstNode compilationUnit)
        {
            foreach (var en in compilationUnit.Descendants.OfType <EntityDeclaration>())
            {
                var def = en.Annotation <IMemberDef>();
                Debug.Assert(def != null);
                if (def == null)
                {
                    continue;
                }

                // The decompiler doesn't remove IteratorStateMachineAttributes/AsyncStateMachineAttribute.
                // These attributes usually contain the name of a type with invalid characters in its name
                // and will prevent the user from compiling the code.
                if (en.SymbolKind == SymbolKind.Method)
                {
                    foreach (var sect in en.Attributes)
                    {
                        foreach (var attr in sect.Attributes)
                        {
                            var ca = attr.Annotation <CustomAttribute>();
                            var fn = ca?.TypeFullName;
                            if (fn == "System.Runtime.CompilerServices.IteratorStateMachineAttribute" ||
                                fn == "System.Runtime.CompilerServices.AsyncStateMachineAttribute")
                            {
                                attr.Remove();
                            }
                        }
                        if (!sect.Attributes.Any())
                        {
                            sect.Remove();
                        }
                    }
                }

                if (makeEverythingPublic)
                {
                    const Modifiers accessFlags = Modifiers.Private | Modifiers.Internal | Modifiers.Protected | Modifiers.Public;
                    en.Modifiers = (en.Modifiers & ~accessFlags) | Modifiers.Public;

                    bool clearModifiers = false;

                    var owner = en.Parent as TypeDeclaration;
                    if (owner?.ClassType == ClassType.Enum || owner?.ClassType == ClassType.Interface)
                    {
                        clearModifiers = true;
                    }
                    else if (en is Accessor)
                    {
                        // If it's a getter/setter/adder/remover, its owner (the property/event) already is public,
                        // so remove the modifier from the accessor
                        clearModifiers = true;
                    }
                    else if (en.SymbolKind == SymbolKind.Destructor)
                    {
                        clearModifiers = true;
                    }
                    else if (en.SymbolKind == SymbolKind.Constructor && en.HasModifier(Modifiers.Static))
                    {
                        clearModifiers = true;
                    }
                    else if (en is MethodDeclaration)
                    {
                        var md = (MethodDeclaration)en;
                        if (!md.PrivateImplementationType.IsNull || (md.Parent as TypeDeclaration)?.ClassType == ClassType.Interface)
                        {
                            clearModifiers = true;
                        }
                    }
                    else if (en is CustomEventDeclaration)
                    {
                        var ed = (CustomEventDeclaration)en;
                        if (!ed.PrivateImplementationType.IsNull || (ed.Parent as TypeDeclaration)?.ClassType == ClassType.Interface)
                        {
                            clearModifiers = true;
                        }
                    }
                    else if (en is PropertyDeclaration)
                    {
                        var pd = (PropertyDeclaration)en;
                        if (!pd.PrivateImplementationType.IsNull || (pd.Parent as TypeDeclaration)?.ClassType == ClassType.Interface)
                        {
                            clearModifiers = true;
                        }
                    }

                    if (clearModifiers)
                    {
                        en.Modifiers &= ~accessFlags;
                    }
                }

                if (partialTypes.Contains(def))
                {
                    var tdecl = en as TypeDeclaration;
                    Debug.Assert(tdecl != null);
                    if (tdecl != null)
                    {
                        tdecl.Modifiers |= Modifiers.Partial;
                        if (!showDefinitions)
                        {
                            tdecl.BaseTypes.Clear();
                            tdecl.Attributes.Clear();
                        }
                    }
                }
                else
                {
                    // The decompiler doesn't support Roslyn yet so remove this since
                    // it will break compilation
                    if (def is TypeDef && def.Name == "<>c")
                    {
                        en.Remove();
                    }

                    if (showDefinitions)
                    {
                        if (!defsToShow.Contains(def))
                        {
                            en.Remove();
                        }
                    }
                    else
                    {
                        if (defsToShow.Contains(def))
                        {
                            en.Remove();
                        }
                        else if (en is CustomEventDeclaration)
                        {
                            // Convert this hidden event to an automatic event

                            var ev = (CustomEventDeclaration)en;
                            var ed = new EventDeclaration();
                            ed.ReturnType = ev.ReturnType.Detach();
                            ed.Modifiers  = ev.Modifiers;
                            ed.Variables.Add(new VariableInitializer(TextColorHelper.GetColor(ev.Annotation <EventDef>()), ev.Name));
                            ed.CopyAnnotationsFrom(ev);
                            ev.ReplaceWith(ed);
                        }
                    }
                }
            }
        }