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