/* * Determine if "classInfo" fully implements "interface". * Note: Returns non-zero on error. */ static int ImplementsInterface(ILNode *node, ILClass *classInfo, ILClass *interface, ILGenInterfaceErrorFunc error, ILGenInterfaceProxyFunc proxy, ILClass **visited, int *visitedSize) { int posn; ILMember *member; int sawErrors; /* Bail out if we've already visited this interface */ for(posn = 0; posn < *visitedSize; ++posn) { if(visited[posn] == interface) { return 0; } } visited[(*visitedSize)++] = interface; /* Process all members within the interface */ sawErrors = 0; member = 0; while((member = ILClassNextMember(interface, member)) != 0) { if(ILMember_IsMethod(member) && !ILMethod_HasSpecialName(member)) { sawErrors |= ImplementsMethod(node, classInfo, (ILMethod *)member, error, proxy); } else if(ILMember_IsProperty(member) || ILMember_IsEvent(member)) { sawErrors |= ImplementsMethodSem(node, classInfo, member, error, proxy); } } /* Process all of the parent interfaces */ return sawErrors | ImplementsAllInterfaces(node, classInfo, interface, error, proxy, visited, visitedSize); }
/* * Expand the instantiations in a class. Returns zero if out of memory. */ static int ExpandInstantiations(ILImage *image, ILClass *classInfo, ILType *classType, ILType *classParams) { ILClass *origClass; ILMember *member; ILMethod *newMethod; ILField *newField; ILEvent *newEvent; ILType *signature; ILImplements *impl; ILClass *tempInfo; /* Bail out if not a "with" type, since the instantiation would have already been taken care of by "ILClassFromType" */ if(!ILType_IsWith(classType)) { return 1; } /* Find the original class underlying the type */ origClass = ILClassFromType(image, 0, ILTypeGetWithMain(classType), 0); if(!origClass) { return 0; } origClass = ILClassResolve(origClass); /* Copy across the class attributes */ ILClassSetAttrs(classInfo, ~((ILUInt32)0), ILClass_Attrs(origClass)); /* Mark this class as being expanded, to deal with circularities */ classInfo->attributes |= IL_META_TYPEDEF_CLASS_EXPANDED; /* Expand the parent class and interfaces */ if(origClass->parent) { ILClass *parentClass; parentClass = ILClassExpand (image, ILClass_ParentClass(origClass), classParams, 0); if(!parentClass) { classInfo->parent = 0; return 0; } classInfo->parent = ILToProgramItem(parentClass); } impl = _ILClass_Implements(origClass); while(impl) { tempInfo = ILImplements_InterfaceClass(impl); tempInfo = ILClassExpand(image, tempInfo, classParams, 0); if(!tempInfo) { return 0; } if(!ILClassAddImplements(classInfo, ILToProgramItem(tempInfo), 0)) { return 0; } impl = _ILImplements_NextImplements(impl); } /* Expand the methods and fields */ member = 0; while((member = ILClassNextMember(origClass, member)) != 0) { switch(ILMemberGetKind(member)) { case IL_META_MEMBERKIND_METHOD: { newMethod = ILMethodCreateInstance(image, (ILMethod *)member, classInfo, classParams, 0); if(!newMethod) { return 0; } } break; case IL_META_MEMBERKIND_FIELD: { /* Create a new field */ newField = (ILField *)ILMemberCreateInstance(member, classInfo); if(!newField) { return 0; } /* Copy the original field's properties */ signature = ILTypeInstantiate(image->context, ILMember_Signature(member), classParams, 0); if(!signature) { return 0; } else { ILMemberSetSignature((ILMember *)newField, signature); } } break; case IL_META_MEMBERKIND_EVENT: { /* Create a new event */ newEvent = (ILEvent *)ILMemberCreateInstance(member, classInfo); if(!newEvent) { return 0; } /* Copy the original field's properties */ signature = ILTypeInstantiate(image->context, ILMember_Signature(member), classParams, 0); if(!signature) { return 0; } else { ILMemberSetSignature((ILMember *)newEvent, signature); } } break; case IL_META_MEMBERKIND_PROPERTY: { /* TODO */ } break; case IL_META_MEMBERKIND_OVERRIDE: { /* TODO */ } break; case IL_META_MEMBERKIND_PINVOKE: { /* TODO */ } break; } } /* Done */ return 1; }