Beispiel #1
0
        /// <summary>
        /// Adds the property.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="propertyDef">The property def.</param>
        private void AddProperty(NType parent, PropertyDefinition propertyDef)
        {
            var propertyId = DocIdHelper.GetXmlId(propertyDef);
            var property   = (NProperty)_registry.FindById(propertyId);

            if (property == null)
            {
                property = NewInstance <NProperty>(parent.Namespace, propertyDef);
                _registry.Register(property);
                property.Namespace = parent.Namespace;

                property.MemberType   = NMemberType.Property;
                property.PropertyType = GetTypeReference(propertyDef.PropertyType);
                property.GetMethod    = AddMethod(property, propertyDef.GetMethod, true);
                property.SetMethod    = AddMethod(property, propertyDef.SetMethod, true);

                parent.AddMember(property);
                parent.HasProperties = true;

                // Setup visibility based on method
                var refMethod = property.GetMethod ?? property.SetMethod;
                property.Visibility = refMethod.Visibility;
                property.IsStatic   = refMethod.IsStatic;
                property.IsFinal    = refMethod.IsFinal;
                property.IsAbstract = refMethod.IsAbstract;

                property.SeeAlsos.Add(new NSeeAlso(parent));
                property.SeeAlsos.Add(new NSeeAlso(parent.Namespace));

                UpdatePageTitle(property);
            }

            property.SetApiGroup(CurrentMergeGroup, true);
        }
Beispiel #2
0
        /// <summary>
        /// Adds the event.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="eventDef">The event def.</param>
        private void AddEvent(NType parent, EventDefinition eventDef)
        {
            var eventId = DocIdHelper.GetXmlId(eventDef);
            var @event  = (NEvent)_registry.FindById(eventId);

            if (@event == null)
            {
                @event = NewInstance <NEvent>(parent.Namespace, eventDef);
                _registry.Register(@event);

                @event.MemberType = NMemberType.Event;
                @event.EventType  = this.GetTypeReference(eventDef.EventType);

                parent.AddMember(@event);
                parent.HasEvents = true;

                var addMethod    = AddMethod(@event, eventDef.AddMethod, true);
                var removeMethod = AddMethod(@event, eventDef.RemoveMethod, true);

                // Setup visibility based on event add/remove methods
                var refMethod = addMethod ?? removeMethod;
                @event.Visibility = refMethod.Visibility;
                @event.IsStatic   = refMethod.IsStatic;
                @event.IsFinal    = refMethod.IsFinal;
                @event.IsAbstract = refMethod.IsAbstract;

                // Add SeeAlso
                @event.SeeAlsos.Add(new NSeeAlso(parent));
                @event.SeeAlsos.Add(new NSeeAlso(parent.Namespace));

                UpdatePageTitle(@event);
            }

            @event.SetApiGroup(CurrentMergeGroup, true);
        }
Beispiel #3
0
        /// <summary>
        /// Adds the field.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="fieldDef">The field def.</param>
        private void AddField(NType parent, FieldDefinition fieldDef)
        {
            if (fieldDef.IsSpecialName)
            {
                return;
            }

            var fieldId = DocIdHelper.GetXmlId(fieldDef);
            var field   = (NField)_registry.FindById(fieldId);

            if (field == null)
            {
                field = NewInstance <NField>(parent.Namespace, fieldDef);
                _registry.Register(field);
                field.MemberType = NMemberType.Field;
                field.FieldType  = GetTypeReference(fieldDef.FieldType);

                // Setup visibility
                field.IsStatic = fieldDef.IsStatic;

                if (fieldDef.IsPublic)
                {
                    field.Visibility = NVisibility.Public;
                }
                else if (fieldDef.IsPrivate)
                {
                    field.Visibility = NVisibility.Private;
                }
                else if (fieldDef.IsAssembly)
                {
                    field.Visibility = NVisibility.Internal;
                }
                else if (fieldDef.IsFamily)
                {
                    field.Visibility = NVisibility.Protected;
                }
                else if (fieldDef.IsFamilyOrAssembly)
                {
                    field.Visibility = NVisibility.ProtectedInternal;
                }

                if (fieldDef.Constant != null)
                {
                    field.ConstantValue = GetTextFromValue(fieldDef.Constant);
                }

                parent.AddMember(field);
                parent.HasFields = true;

                field.SeeAlsos.Add(new NSeeAlso(parent));
                field.SeeAlsos.Add(new NSeeAlso(parent.Namespace));

                UpdatePageTitle(field);
            }

            field.SetApiGroup(CurrentMergeGroup, true);
        }
Beispiel #4
0
        /// <summary>
        /// New instance of a <see cref="IModelReference"/>.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="memberRef">The type def.</param>
        /// <returns></returns>
        private T NewInstance <T>(NNamespace @nameSpace, MemberReference memberRef) where T : NMember, new()
        {
            var id     = DocIdHelper.GetXmlId(memberRef);
            var member = new T {
                Name = memberRef.Name, FullName = memberRef.FullName, Id = id
            };

            member.PageId        = PageIdFunction(member);
            member.DocNode       = _source.Document.FindMemberDoc(member.Id);
            member.DeclaringType = GetTypeReference(memberRef.DeclaringType);
            member.Namespace     = @nameSpace;
            member.Assembly      = CurrentAssembly;
            this.FillMemberReference(member, memberRef);
            // Add generic parameter contraints
            return(member);
        }
Beispiel #5
0
        private void FillMemberReference(INMemberReference memberRef, MemberReference cecilMemberRef)
        {
            memberRef.Id       = DocIdHelper.GetXmlId(cecilMemberRef);
            memberRef.PageId   = PageIdFunction(memberRef);
            memberRef.Name     = ReplacePrimitive(cecilMemberRef.Name, cecilMemberRef.FullName);
            memberRef.FullName = cecilMemberRef.FullName;

            // Load system documentation if needed
            LoadSystemAssemblyDoc(memberRef, cecilMemberRef);

            var typeDef = cecilMemberRef as TypeReference;

            if (typeDef != null)
            {
                memberRef.IsGenericInstance  = typeDef.IsGenericInstance;
                memberRef.IsGenericParameter = typeDef.IsGenericParameter;
                memberRef.IsArray            = typeDef.IsArray;
                memberRef.IsPointer          = typeDef.IsPointer;
                memberRef.IsSentinel         = typeDef.IsSentinel;
                FillGenericParameters(memberRef, typeDef);

                // Handle generic instance
                var genericInstanceDef = typeDef as GenericInstanceType;

                if (genericInstanceDef != null)
                {
                    memberRef.ElementType = GetTypeReference(genericInstanceDef.ElementType);

                    if (genericInstanceDef.GenericArguments.Count > 0)
                    {
                        foreach (var genericArgumentDef in genericInstanceDef.GenericArguments)
                        {
                            var genericArgument = new NTypeReference();
                            FillMemberReference(genericArgument, genericArgumentDef);
                            memberRef.GenericArguments.Add(genericArgument);
                        }

                        // Remove `number from Name
                        memberRef.Name     = BuildGenericName(typeDef.Name, memberRef.GenericArguments);
                        memberRef.FullName = BuildGenericName(typeDef.FullName, memberRef.GenericArguments);
                    }
                }
                else if (memberRef.GenericParameters.Count > 0)
                {
                    // If generic parameters, than rewrite the name/fullname
                    memberRef.Name     = BuildGenericName(typeDef.Name, memberRef.GenericParameters);
                    memberRef.FullName = BuildGenericName(typeDef.FullName, memberRef.GenericParameters);
                }
            }
            else
            {
                var genericParameterProvider = cecilMemberRef as IGenericParameterProvider;
                if (genericParameterProvider != null)
                {
                    this.FillGenericParameters(memberRef, genericParameterProvider);
                    memberRef.Name     = BuildGenericName(memberRef.Name, memberRef.GenericParameters);
                    memberRef.FullName = BuildGenericName(memberRef.FullName, memberRef.GenericParameters);
                }
            }

            var member = memberRef as NMember;

            // Add custom attributes for this member
            if (member != null && cecilMemberRef is ICustomAttributeProvider)
            {
                var attributes = ((ICustomAttributeProvider)cecilMemberRef).CustomAttributes;
                foreach (var customAttribute in attributes)
                {
                    member.Attributes.Add(CustomAttributeToString(member, customAttribute));
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Adds the type.
        /// </summary>
        /// <param name="namespace">The @namespace.</param>
        /// <param name="typeDef">The type def.</param>
        private void AddType(NNamespace @namespace, TypeDefinition typeDef)
        {
            // Todo add configurable filter
            if (!typeDef.IsPublic && !typeDef.IsNestedPublic)
            {
                return;
            }

            var typeId = DocIdHelper.GetXmlId(typeDef);
            var type   = (NType)_registry.FindById(typeId);

            // If this is a new type create and register it
            if (type == null)
            {
                if (typeDef.IsInterface)
                {
                    type            = NewInstance <NInterface>(@namespace, typeDef);
                    type.MemberType = NMemberType.Interface;
                }
                else if (typeDef.IsEnum)
                {
                    type            = NewInstance <NEnum>(@namespace, typeDef);
                    type.MemberType = NMemberType.Enum;
                }
                else if (typeDef.IsValueType)
                {
                    type            = NewInstance <NStruct>(@namespace, typeDef);
                    type.MemberType = NMemberType.Struct;
                }
                else if (MonoCecilHelper.IsDelegate(typeDef))
                {
                    type            = NewInstance <NDelegate>(@namespace, typeDef);
                    type.MemberType = NMemberType.Delegate;
                }
                else if (typeDef.IsClass)
                {
                    type            = NewInstance <NClass>(@namespace, typeDef);
                    type.MemberType = NMemberType.Class;
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Unsupported type [{0}]", typeDef.FullName));
                }

                // Fix nested type name
                if (typeDef.IsNestedPublic)
                {
                    type.Name     = type.DeclaringType.Name + "." + type.Name;
                    type.FullName = type.FullName.Replace("/", ".");
                }

                _registry.Register(type);
                @namespace.AddType(type);

                // Add reference to all base types
                var baseTypeDefinition = typeDef;
                do
                {
                    baseTypeDefinition = MonoCecilHelper.GetBaseType(baseTypeDefinition);
                    if (baseTypeDefinition != null)
                    {
                        type.Bases.Add(GetTypeReference(baseTypeDefinition));
                    }
                } while (baseTypeDefinition != null);

                // Flattened hierarchy initialized with all base types
                // Derived types will be added at a later pass, when types in all asemblies
                // will be discovered.
                var reverseBases = new List <INMemberReference>(type.Bases);
                reverseBases.Reverse();
                for (int i = 0; i < reverseBases.Count; i++)
                {
                    type.FlattenedHierarchy.Add(new Tuple <int, INMemberReference>(i, reverseBases[i]));
                }
                // Add this type itself to its flattened hierarchy
                type.FlattenedHierarchy.Add(new Tuple <int, INMemberReference>(reverseBases.Count, type));

                // Add reference to inherited interfaces
                foreach (var typeReference in typeDef.Interfaces)
                {
                    type.Interfaces.Add(GetTypeReference(typeReference));
                }

                if (typeDef.IsPublic)
                {
                    type.Visibility = NVisibility.Public;
                }
                else if (typeDef.IsNotPublic)
                {
                    type.Visibility = NVisibility.Private;
                }
                type.IsAbstract = typeDef.IsAbstract;
                type.IsFinal    = typeDef.IsSealed;

                // Revert back declaration abstract sealed class are actually declared as static class
                if (type is NClass && type.IsAbstract && type.IsFinal)
                {
                    type.IsStatic   = true;
                    type.IsAbstract = false;
                    type.IsFinal    = false;
                }
                else if (type is NEnum || type is NStruct || type is NDelegate)
                {
                    // We know that enum is sealed, so don't duplicate it
                    type.IsFinal = false;
                }

                // Reconstruct StructLayout attribute
                if (typeDef.IsExplicitLayout || typeDef.IsSequentialLayout)
                {
                    var layout = new StringBuilder();
                    layout.Append("StructLayoutAttribute(");
                    if (typeDef.IsExplicitLayout)
                    {
                        layout.Append("LayoutKind.Explicit");
                    }
                    else if (typeDef.IsSequentialLayout)
                    {
                        layout.Append("LayoutKind.Sequential");
                    }
                    else
                    {
                        layout.Append("LayoutKind.Auto");
                    }

                    if (typeDef.IsUnicodeClass)
                    {
                        layout.Append(", CharSet = CharSet.Unicode");
                    }
                    else if (typeDef.IsAnsiClass)
                    {
                        layout.Append(", CharSet = CharSet.Ansi");
                    }
                    else if (typeDef.IsAutoClass)
                    {
                        layout.Append(", CharSet = CharSet.Auto");
                    }

                    if (typeDef.PackingSize != 0)
                    {
                        layout.Append(", Pack = ").Append(typeDef.PackingSize);
                    }

                    if (typeDef.ClassSize != 0)
                    {
                        layout.Append(", Size = ").Append(typeDef.ClassSize);
                    }

                    layout.Append(")");
                    type.Attributes.Add(layout.ToString());
                }

                // Reconstruct Serializable attribute
                if (typeDef.IsSerializable)
                {
                    type.Attributes.Add("SerializableAttribute");
                }

                type.SeeAlsos.Add(new NSeeAlso(@namespace));
            }

            // Add current group
            type.SetApiGroup(CurrentMergeGroup, true);

            // Because a type in a different assemblies can have new methods/properties/fields...etc.
            // We need to check that there is no new members

            // Add methods, constructors, operators. Todo add configurable filter
            foreach (var method in typeDef.Methods.Where(this.IsMemberToDisplay))
            {
                AddMethod(type, method);
            }

            // Add fields. Todo add configurable filter
            foreach (var field in typeDef.Fields.Where(this.IsMemberToDisplay))
            {
                AddField(type, field);
            }

            // Add events. Todo add configurable filter
            foreach (var eventInfo in typeDef.Events.Where(this.IsMemberToDisplay))
            {
                AddEvent(type, eventInfo);
            }

            // Add properties Todo add configurable filter
            foreach (var property in typeDef.Properties.Where(this.IsMemberToDisplay))
            {
                AddProperty(type, property);
            }

            // For enumeration, we are only using MsdnId from enum
            if (type is NEnum)
            {
                foreach (var field in type.Fields)
                {
                    field.MsdnId = type.MsdnId;
                }
            }

            // Add nested types to the global namespace.
            foreach (var nestedType in typeDef.NestedTypes)
            {
                AddType(@namespace, nestedType);
            }

            UpdatePageTitle(type);
        }