示例#1
0
        public static List <ITypeDefinitionMember> FindRelatedExternalMembers(ITypeDefinitionMember member, CanIncludeCheck canInclude)
        {
            List <ITypeDefinitionMember>      relatedMembers     = new List <ITypeDefinitionMember>();
            Dictionary <uint, ITypeReference> participatingTypes = new Dictionary <uint, ITypeReference>();

            ITypeDefinition currentType = member.ContainingTypeDefinition;

            do
            {
                //
                // add the type
                //
                if (!canInclude(Util.CanonicalizeTypeReference(currentType)))
                {
                    participatingTypes.Add(currentType.InternedKey, currentType);
                }

                //
                // add any interfaces it implements that are part of the closure
                //

                foreach (ITypeReference iface in currentType.Interfaces)
                {
                    INamedTypeReference ifaceTemplate = Util.CanonicalizeTypeReference(iface);
                    // check the closure against the template type, but add
                    // the specialized type to participatingTypes so that
                    // argument matching works
                    if (!canInclude(ifaceTemplate) &&
                        !participatingTypes.ContainsKey(iface.InternedKey))
                    {
                        // Should we add ifaceTemplate or iface?
                        participatingTypes.Add(iface.InternedKey, iface);
                    }
                }

                //
                // go up to the base type
                //
                currentType = TypeHelper.BaseClass(currentType);
            }while (currentType != null);

            foreach (ITypeReference type in participatingTypes.Values)
            {
                ITypeDefinitionMember relatedMember = FindRelatedMember(type, member);
                if (null != relatedMember)
                {
                    relatedMembers.Add(relatedMember);
                }
            }

            return(relatedMembers);
        }
示例#2
0
        private bool ShouldHideMember(ITypeDefinitionMember member)
        {
            bool shouldHide = false;

            INamedTypeDefinition type = Util.ContainingTypeDefinition(member);

            if (IsHiddenMemberCandidate(member))
            {
                if (!TypeIsVisibleInApi(type))
                {
                    // Declaring type is hidden, only modify the visibility on a
                    // member when its corresponding member on a public base type
                    // was hidden.

                    INamedTypeDefinition baseType = Util.CanonicalizeType(TypeHelper.BaseClass(type));
                    while (baseType != null && baseType != Dummy.Type)
                    {
                        if (TypeIsVisibleInApi(baseType))
                        {
                            ITypeDefinitionMember relatedMember = Util.FindRelatedMember(baseType, member);
                            if (relatedMember != null)
                            {
                                ITypeDefinitionMember canonicalizedRelatedMember = Util.CanonicalizeMember(relatedMember);
                                if (_depot.ContainsMember(canonicalizedRelatedMember) &&
                                    ShouldHideMember(canonicalizedRelatedMember))
                                {
                                    shouldHide = true;
                                    break;
                                }
                            }
                        }
                        baseType = Util.CanonicalizeType(TypeHelper.BaseClass(baseType));
                    }
                }
                else
                {
                    // declaring type is public, we must hide the member.
                    shouldHide = true;
                }
            }

            return(shouldHide);
        }
示例#3
0
        public static List <ITypeDefinitionMember> FindRelatedMembers(ITypeDefinitionMember member, TypeIncluded includeType)
        {
            List <ITypeDefinitionMember>      relatedMembers     = new List <ITypeDefinitionMember>();
            Dictionary <uint, ITypeReference> participatingTypes = new Dictionary <uint, ITypeReference>();

            ITypeDefinition currentType = member.ContainingTypeDefinition;

            do
            {
                //
                // add the type
                //
                participatingTypes.Add(currentType.InternedKey, currentType);

                //
                // add any interfaces it implements that are part of the closure
                //
                foreach (ITypeReference iface in currentType.Interfaces)
                {
                    INamedTypeReference ifaceTemplate = Util.CanonicalizeTypeReference(iface);
                    // check the closure against the template type, but add
                    // the specialized type to participatingTypes so that
                    // argument matching works
                    if (includeType(ifaceTemplate) &&
                        !participatingTypes.ContainsKey(iface.InternedKey))
                    {
                        // Should we add ifaceTemplate or iface?
                        participatingTypes.Add(iface.InternedKey, iface);
                    }
                }

                //
                // go up to the base type
                //
                currentType = TypeHelper.BaseClass(currentType);
            }while (currentType != null);

            foreach (ITypeReference type in participatingTypes.Values)
            {
                ITypeDefinitionMember relatedMember = FindRelatedMember(type, member);
                if (null != relatedMember)
                {
                    relatedMembers.Add(relatedMember);
                }
                // TODO: Review
                foreach (IMethodImplementation methodImpl in Util.CanonicalizeType(type).ExplicitImplementationOverrides)
                {
                    ITypeDefinitionMember implementingMethod = Util.CanonicalizeMember(methodImpl.ImplementingMethod);
                    ITypeDefinitionMember implementedMethod  = Util.CanonicalizeMember(methodImpl.ImplementedMethod);
                    bool implementedTypeIncluded             = includeType(Util.CanonicalizeType(implementedMethod.ContainingType));

                    if ((implementedMethod == member) ||
                        (implementingMethod == member && implementedTypeIncluded))
                    {
                        if (!relatedMembers.Contains(implementingMethod))
                        {
                            relatedMembers.Add(implementingMethod);
                        }
                        if (!relatedMembers.Contains(implementedMethod))
                        {
                            relatedMembers.Add(implementedMethod);
                        }
                    }
                }
            }

            return(relatedMembers);
        }
示例#4
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);
        }
示例#5
0
 public CalledBaseCtorFinder(IMethodDefinition ctor)
 {
     _targetType = Util.CanonicalizeType(TypeHelper.BaseClass(Util.ContainingTypeDefinition(ctor)));
     _baseCtor   = null;
 }
示例#6
0
        //
        // Some types may have base types with no default ctors
        // and no ctors themselves.  In those cases, the compiler
        // cannot instantiate the type without an explicit ctor
        // that calls one of the included base type ctors.
        //
        private void GenerateWorkForCtors(INamedTypeDefinition type, IClosureVisitor visitor)
        {
            if (TypeHelper.BaseClass(type) == null)
            {
                return;
            }

            List <IMethodDefinition> ctors = GetCtors(type, true);

            if (ctors.Count != 0)
            {
                return;
            }

            List <IMethodDefinition> baseCtors = GetCtors(Util.CanonicalizeType(TypeHelper.BaseClass(type)), true);

            if (baseCtors.Count == 0)
            {
                return;
            }

            int nDefaultCtors = 0;

            foreach (IMethodDefinition ctor in baseCtors)
            {
                if (Util.ParameterCount(ctor) == 0)
                {
                    nDefaultCtors++;
                }
            }

            if (nDefaultCtors != 0)
            {
                return;
            }

            // TODO: Shouldn't this be part of implclosure?
            ctors = GetCtors(type, false);
            foreach (IMethodDefinition baseCtor in baseCtors)
            {
                foreach (IMethodDefinition ctor in ctors)
                {
                    if (MethodCallsMethod(ctor, baseCtor))
                    {
                        AddMemberReference(ctor);
                        return;  // @TODO: we may need to add more than just the first one we find..
                    }
                }
            }

            // at this point, no included ctor in the base type is
            // being called by any of the ctors in the derived type
            // so we have to get a little more creative

            if (ctors.Count > 0)
            {
                IMethodDefinition fallback = FindCalledBaseCtor(ctors[0]);
                if (null != fallback)
                {
                    AddMemberReference(ctors[0]);
                    AddMemberReference(fallback);
                }
            }
        }
示例#7
0
        public override void Visit(ITypeDefinition type)
        {
            // prevent cycles
            if (_visitedTypes.ContainsKey(type.InternedKey))
            {
                return;
            }
            _visitedTypes.Add(type.InternedKey, null);

            AddTypeReference(Util.CanonicalizeTypeReference(type));

            INestedTypeDefinition nestedType = type as INestedTypeDefinition;

            if (nestedType != null)
            {
                Visit(nestedType.ContainingTypeDefinition);
            }

            Visit(type.Attributes);

            if (type.HasDeclarativeSecurity)
            {
                Visit(type.SecurityAttributes);
            }

            Visit(type.BaseClasses);

            // Don't visit type.Interfaces here, since we might not need to include all those interfaces in the closure.
            // We will include any interfaces used elsewhere in the api/implementation

            if (type.IsGeneric)
            {
                Visit(type.GenericParameters);
            }

            foreach (ITypeDefinitionMember member in type.Members)
            {
                List <ITypeDefinitionMember> members = Util.FindRelatedExternalMembers(member, m_implModel.CanInclude);
                if (members.Count != 0)
                {
                    // This member is related to an external member, so we need to add it here.
                    AddMemberReference(member);
                    // TODO: Only add if the related member is abstract?
                }
            }

            // Instead of visiting all the members, let's just add the things that are implied
            foreach (IMethodDefinition meth in type.Methods)
            {
                // visit .cctor for the type
                if (meth.IsStaticConstructor)
                {
                    AddMemberReference(meth);
                }

                // @TODO: this is lame--a base type of this type may not have
                // a default constructor and we may not ever encounter code
                // that actually creates *this* type, so we may end up in a
                // situation where we cannot compile this type because we
                // don't have a ctor that satisfies the base type's ctor(s).
                //
                // for now, just add any default .ctor and hope that's good enough
                if (meth.IsConstructor && TypeHelper.BaseClass(type) != null && Util.ParameterCount(meth) == 0)
                {
                    AddMemberReference(meth);
                }
            }

            // TODO: _options.FieldOptions == FieldOptions.KeepAll needs to be checked for api closure as well?
            if (_options.FieldOptions == FieldOptions.KeepAll ||
                (_options.FieldOptions == FieldOptions.KeepAllValueTypeFields && type.IsValueType))
            {
                foreach (IFieldDefinition field in type.Fields)
                {
                    // Include all static literal fields.
                    if (!field.IsStatic || field.IsCompileTimeConstant)
                    {
                        AddMemberReference(field);
                    }
                }
            }

            //Visit(type.TemplateArguments);
            //Visit(type.TemplateParameters);
        }