Ejemplo n.º 1
0
 private void AddRootMember(ThinMember member)
 {
     if (member.Metadata == null)
     {
         if (!_missingMembers.Contains(member))
         {
             _missingMembers.Add(member);
         }
     }
     else
     {
         if (!_rootMembers.ContainsKey(member.Metadata))
         {
             _rootMembers.Add(member.Metadata, member);
         }
     }
 }
Ejemplo n.º 2
0
        // Special case: If closureStatus == ApiRoot this will automatically
        // convert it to ImplRoot for internal types
        // TODO: Visitor should set status instead of this.
        public ThinModel ExportModel(IncludeStatus closureStatus)
        {
            _closureStatus = closureStatus;

            int nApiTypes          = 0;
            int nApiTypeForwarders = 0;
            int nApiMembers        = 0;

            ThinModel thinModel = new ThinModel(_thinModel.Options);
            Dictionary <String, ThinAssembly>           assemblies = new Dictionary <String, ThinAssembly>(_depot.AssembliesClosure.Count);
            Dictionary <INamedTypeDefinition, ThinType> types      = new Dictionary <INamedTypeDefinition, ThinType>(_depot.TypesClosure.Count);

            foreach (IAssembly assembly in _depot.AssembliesClosure.Values)
            {
                ThinAssembly thinAsm = new ThinAssembly(_thinModel, assembly.Name.Value, GetIncludeStatus(assembly), assembly);
                thinModel.Assemblies.Add(thinAsm.Name, thinAsm);
                assemblies.Add(assembly.Name.Value, thinAsm);
            }

            foreach (INamedTypeDefinition type in _depot.TypesClosure.Values)
            {
                IAssembly asm = TypeHelper.GetDefiningUnit(type) as IAssembly;
                if (asm != null && assemblies.ContainsKey(asm.Name.Value))
                {
                    VisibilityOverride vis = VisibilityOverride.None;
                    if (ShouldHideType(type))
                    {
                        vis = VisibilityOverride.Internal;
                    }

                    if (closureStatus != IncludeStatus.ApiRoot)
                    {
                        if (TypeIsVisibleInApi(type))
                        {
                            INamedTypeDefinition curType = type;
                            while (curType != null && curType != Dummy.Type && // TODO: Remove dummy check?
                                   CanInclude(curType))
                            {
                                if (WeHidThisType(curType))
                                {
                                    throw new Exception("API closure error!  Base type " + curType + " was hidden, but " + type + " is in the public API");
                                }
                                ITypeReference curTypeRef = TypeHelper.BaseClass(curType);
                                curType = curTypeRef != null?Util.CanonicalizeType(curTypeRef) : null;
                            }
                        }
                    }

                    ThinAssembly declaringAssembly = assemblies[asm.Name.Value];
                    ThinType     thinType          = new ThinType(declaringAssembly, Util.FullyQualifiedTypeNameFromType(type), GetIncludeStatus(type), type, vis);
                    declaringAssembly.Types.Add(thinType.Name, thinType);
                    types.Add(type, thinType);

                    if (thinType.IncludeStatus == IncludeStatus.ApiClosure ||
                        thinType.IncludeStatus == IncludeStatus.ApiRoot ||
                        thinType.IncludeStatus == IncludeStatus.ApiFxInternal)
                    {
                        nApiTypes++;
                    }
                }
                else
                {
                    Console.Error.WriteLine("BclRewriter : warning BR5004 : couldn't find declaring module of type {0} in closure", type);
                }
            }

            foreach (IAliasForType typeForwarder in _depot.TypeForwardersClosure.Values)
            {
                // TODO: Why is this getting an immutable copy of the assembly?
                IAssembly asm = Util.GetDefiningAssembly(typeForwarder);
                if (asm != null && assemblies.ContainsKey(asm.Name.Value))
                {
                    ThinAssembly      declaringAssembly = assemblies[asm.Name.Value];
                    ITypeReference    aliasedType       = typeForwarder.AliasedType;
                    ThinTypeForwarder thinTypeForwarder = new ThinTypeForwarder(declaringAssembly,
                                                                                Util.GetDefiningAssembly(aliasedType).Name.Value,
                                                                                Util.GetTypeName(aliasedType),
                                                                                GetIncludeStatus(typeForwarder),
                                                                                typeForwarder);

                    declaringAssembly.TypeForwarders.Add(thinTypeForwarder.Key, thinTypeForwarder);

                    if (thinTypeForwarder.IncludeStatus == IncludeStatus.ApiClosure ||
                        thinTypeForwarder.IncludeStatus == IncludeStatus.ApiRoot ||
                        thinTypeForwarder.IncludeStatus == IncludeStatus.ApiFxInternal)
                    {
                        nApiTypeForwarders++;
                    }
                }
                else
                {
                    Console.Error.WriteLine("BclRewriter : warning BR5001 : couldn't find declaring module of type forwarder {0} in closure", typeForwarder);
                }
            }

            foreach (ITypeDefinitionMember member in _depot.MembersClosure.Keys)
            {
                INamedTypeDefinition type = Util.ContainingTypeDefinition(member);
                if (types.ContainsKey(type))
                {
                    ThinType      declaringType = types[type];
                    IncludeStatus status        = GetIncludeStatus(member);

                    VisibilityOverride vis = VisibilityOverride.None;
                    if (ShouldHideMember(member))
                    {
                        vis = VisibilityOverride.Internal;
                    }

                    if ((type.IsInterface) &&
                        TypeIsVisibleInApi(type) &&
                        vis == VisibilityOverride.Internal)
                    {
                        throw new Exception(string.Format("Implementation required non-public member on public interface: {0} on {1}. This usually means you added a property to model.xml without adding the corresponding getter or setter.",
                                                          member.Name,
                                                          Util.FullyQualifiedTypeNameFromType(member.ContainingType)));
                    }

                    ThinMember thinMember = new ThinMember(declaringType, member, status, vis);
                    declaringType.Members.Add(thinMember.Key, thinMember);

                    if (thinMember.IncludeStatus == IncludeStatus.ApiClosure ||
                        thinMember.IncludeStatus == IncludeStatus.ApiRoot ||
                        thinMember.IncludeStatus == IncludeStatus.ApiFxInternal)
                    {
                        nApiMembers++;
                    }
                }
                else
                {
                    Console.Error.WriteLine("BclRewriter : warning BR5002 : couldn't find declaring type of member {0} in closure", member);
                }
            }

            foreach (IMethodDefinition method in _depot.MethodsClosure.Values)
            {
                INamedTypeDefinition type = Util.ContainingTypeDefinition(method);
                if (types.ContainsKey(type))
                {
                    ThinType      declaringType = types[type];
                    IncludeStatus status        = GetIncludeStatus(method);

                    VisibilityOverride vis = VisibilityOverride.None;
                    if (ShouldHideMember(method))
                    {
                        vis = VisibilityOverride.Internal;
                    }

                    if ((type.IsInterface) &&
                        TypeIsVisibleInApi(type) &&
                        vis == VisibilityOverride.Internal)
                    {
                        //throw new Exception(string.Format("WARNING: implementation required non-public member on public interface: {0} on {1}. This usually means you added a property to model.xml without adding the corresponding getter or setter.",
                        //    method.Name,
                        //    Util.FullyQualifiedTypeNameFromType(method.ContainingType)));
                    }

                    ThinMember thinMember = new ThinMember(declaringType, method, status, vis);
                    if (declaringType.Members.ContainsKey(thinMember.Key))
                    {
                        throw new Exception(String.Format("Found two members with the same signature: {0}", thinMember.Key));
                    }
                    declaringType.Members.Add(thinMember.Key, thinMember);

                    if (thinMember.IncludeStatus == IncludeStatus.ApiClosure ||
                        thinMember.IncludeStatus == IncludeStatus.ApiRoot ||
                        thinMember.IncludeStatus == IncludeStatus.ApiFxInternal)
                    {
                        nApiMembers++;
                    }
                }
                else
                {
                    Console.Error.WriteLine("BclRewriter : warning BR5003 : couldn't find declaring type of method {0} in closure", method);
                }
            }

            foreach (ThinMember thinMember in _missingMembers)
            {
                ThinType   typeToExtend  = types[thinMember.DeclaringType.Metadata];
                ThinMember newThinMember = new ThinMember(typeToExtend, thinMember);
                if (!typeToExtend.Members.ContainsKey(newThinMember.Key))
                {
                    typeToExtend.Members.Add(newThinMember.Key, newThinMember);
                }
            }

            return(thinModel);
        }