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