/// <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); }
/// <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); }
/// <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); }
/// <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); }
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)); } } }
/// <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); }