/*
 * 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);
}
Example #2
0
/*
 * 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;
}