MemberList GetMemberList()
        {
            var result = LazyInit.VolatileRead(ref this.memberList);

            if (result != null)
            {
                return(result);
            }
            List <IUnresolvedMember>   unresolvedMembers  = new List <IUnresolvedMember>();
            List <ITypeResolveContext> contextPerMember   = new List <ITypeResolveContext>();
            List <PartialMethodInfo>   partialMethodInfos = null;
            bool addDefaultConstructorIfRequired          = false;

            foreach (IUnresolvedTypeDefinition part in parts)
            {
                ITypeResolveContext parentContextForPart = part.CreateResolveContext(parentContext);
                ITypeResolveContext contextForPart       = parentContextForPart.WithCurrentTypeDefinition(this);
                foreach (var member in part.Members)
                {
                    IUnresolvedMethod method = member as IUnresolvedMethod;
                    if (method != null && method.IsPartial)
                    {
                        // Merge partial method declaration and implementation
                        if (partialMethodInfos == null)
                        {
                            partialMethodInfos = new List <PartialMethodInfo>();
                        }
                        PartialMethodInfo newInfo      = new PartialMethodInfo(method, contextForPart);
                        PartialMethodInfo existingInfo = null;
                        foreach (var info in partialMethodInfos)
                        {
                            if (newInfo.IsSameSignature(info, Compilation.NameComparer))
                            {
                                existingInfo = info;
                                break;
                            }
                        }
                        if (existingInfo != null)
                        {
                            // Add the unresolved method to the PartialMethodInfo:
                            existingInfo.AddPart(method, contextForPart);
                        }
                        else
                        {
                            partialMethodInfos.Add(newInfo);
                        }
                    }
                    else
                    {
                        unresolvedMembers.Add(member);
                        contextPerMember.Add(contextForPart);
                    }
                }

                addDefaultConstructorIfRequired |= part.AddDefaultConstructorIfRequired;
            }
            if (addDefaultConstructorIfRequired)
            {
                TypeKind kind = this.Kind;
                if (kind == TypeKind.Class && !this.IsStatic && !unresolvedMembers.Any(m => m.EntityType == EntityType.Constructor && !m.IsStatic) ||
                    kind == TypeKind.Enum || kind == TypeKind.Struct)
                {
                    contextPerMember.Add(parts[0].CreateResolveContext(parentContext).WithCurrentTypeDefinition(this));
                    unresolvedMembers.Add(DefaultUnresolvedMethod.CreateDefaultConstructor(parts[0]));
                }
            }
            result = new MemberList(contextPerMember, unresolvedMembers, partialMethodInfos);
            return(LazyInit.GetOrSet(ref this.memberList, result));
        }
コード例 #2
0
        bool isSynthetic = true;         // true if all parts are synthetic

        public DefaultResolvedTypeDefinition(ITypeResolveContext parentContext, params IUnresolvedTypeDefinition[] parts)
        {
            if (parentContext == null || parentContext.CurrentAssembly == null)
            {
                throw new ArgumentException("Parent context does not specify any assembly", "parentContext");
            }
            if (parts == null || parts.Length == 0)
            {
                throw new ArgumentException("No parts were specified", "parts");
            }
            this.parentContext = parentContext;
            this.parts         = parts;
            ITypeResolveContext contextForTypeParameters = parts[0].CreateResolveContext(parentContext);

            contextForTypeParameters = contextForTypeParameters.WithCurrentTypeDefinition(this);
            if (parentContext.CurrentTypeDefinition == null || parentContext.CurrentTypeDefinition.TypeParameterCount == 0)
            {
                this.TypeParameters = parts[0].TypeParameters.CreateResolvedTypeParameters(contextForTypeParameters);
            }
            else
            {
                // This is a nested class inside a generic class; copy type parameters from outer class if we can:
                var outerClass = parentContext.CurrentTypeDefinition;
                ITypeParameter[] typeParameters = new ITypeParameter[parts[0].TypeParameters.Count];
                for (int i = 0; i < typeParameters.Length; i++)
                {
                    var unresolvedTP = parts[0].TypeParameters[i];
                    if (i < outerClass.TypeParameterCount && outerClass.TypeParameters[i].Name == unresolvedTP.Name)
                    {
                        typeParameters[i] = outerClass.TypeParameters[i];
                    }
                    else
                    {
                        typeParameters[i] = unresolvedTP.CreateResolvedTypeParameter(contextForTypeParameters);
                    }
                }
                this.TypeParameters = Array.AsReadOnly(typeParameters);
            }
            List <IUnresolvedAttribute> unresolvedAttributes = new List <IUnresolvedAttribute>();
            List <ITypeResolveContext>  contextPerAttribute  = new List <ITypeResolveContext>();
            List <ITypeResolveContext>  contextPerMember     = new List <ITypeResolveContext>();
            bool addDefaultConstructorIfRequired             = false;

            foreach (IUnresolvedTypeDefinition part in parts)
            {
                ITypeResolveContext parentContextForPart = part.CreateResolveContext(parentContext);
                ITypeResolveContext contextForPart       = parentContextForPart.WithCurrentTypeDefinition(this);
                foreach (var attr in part.Attributes)
                {
                    unresolvedAttributes.Add(attr);
                    contextPerAttribute.Add(parentContextForPart);
                }
                foreach (var member in part.Members)
                {
                    unresolvedMembers.Add(member);
                    contextPerMember.Add(contextForPart);
                }

                isAbstract  |= part.IsAbstract;
                isSealed    |= part.IsSealed;
                isShadowing |= part.IsShadowing;
                isSynthetic &= part.IsSynthetic;                 // true if all parts are synthetic

                DefaultUnresolvedTypeDefinition dutd = part as DefaultUnresolvedTypeDefinition;
                if (dutd != null)
                {
                    addDefaultConstructorIfRequired |= dutd.AddDefaultConstructorIfRequired;
                }

                // internal is the default, so use another part's accessibility until we find a non-internal accessibility
                if (accessibility == Accessibility.Internal)
                {
                    accessibility = part.Accessibility;
                }
            }
            if (addDefaultConstructorIfRequired)
            {
                TypeKind kind = this.Kind;
                if (kind == TypeKind.Class && !this.IsStatic && !unresolvedMembers.Any(m => m.EntityType == EntityType.Constructor && !m.IsStatic) ||
                    kind == TypeKind.Enum || kind == TypeKind.Struct)
                {
                    contextPerMember.Add(parts[0].CreateResolveContext(parentContext).WithCurrentTypeDefinition(this));
                    unresolvedMembers.Add(DefaultUnresolvedMethod.CreateDefaultConstructor(parts[0]));
                }
            }
            this.Attributes      = new ProjectedListWithContextPerElement <ITypeResolveContext, IUnresolvedAttribute, IAttribute>(contextPerAttribute, unresolvedAttributes, (c, a) => a.CreateResolvedAttribute(c));
            this.resolvedMembers = new ProjectedListWithContextPerElement <ITypeResolveContext, IUnresolvedMember, IMember>(contextPerMember, unresolvedMembers, (c, m) => m.CreateResolved(c));
        }