public override void VisitIter(IterDefinition iter)
{
iter.Arguments.Accept(this);
iter.MoveNextArguments.Accept(this);
iter.ReturnType.Accept(this);
TypeBuilder typeBuilder = currentClass.TypeBuilder;
try {
CheckMethodConfliction(currentClass.TypeData, iter.Name,
iter.ReturnType.NodeType,
iter.Arguments);
}
catch (MethodConflictionException e) {
report.Error(iter.Location, e.Message);
return;
}
ArrayList conformableMethods =
CheckMethodConformance(currentClass.TypeData, iter.Name,
iter.ReturnType.NodeType,
iter.Arguments,
ancestorMethods);
string baseName = iter.Name.Substring(0, iter.Name.Length - 1);
string creatorName = "__itercreate" + iterCount + "_" + baseName;
Type[] iterTypeAncestors = new Type[conformableMethods.Count];
int i = 0;
foreach (MethodData m in conformableMethods) {
iterTypeAncestors[i++] = m.IterType.RawType;
}
iter.TypeBuilder =
typeBuilder.DefineNestedType("__itertype" + iterCount +
"_" + baseName,
TypeAttributes.Class |
TypeAttributes.NestedPublic,
typeof(object),
iterTypeAncestors);
DefineIterTypeParameters(iter);
TypeData iterType = typeManager.GetTypeData(iter.TypeBuilder);
if (currentClass.TypeParameters.Length > 0) {
TypeData td = iterType.GetGenericTypeDefinition();
iter.BoundType =
td.BindGenericParameters(currentClass.TypeParameters);
}
else
iter.BoundType = iterType;
TypeData boundReceiverType;
if (iter.TypeParameters.Length > 0) {
TypeData td = currentClass.TypeData;
boundReceiverType =
td.BindGenericParameters(iter.TypeParameters);
}
else {
boundReceiverType = currentClass.TypeData;
}
ArrayList list = new ArrayList();
list.Add(boundReceiverType.RawType);
foreach (Argument arg in iter.Arguments) {
if (arg.Mode == ArgumentMode.Once)
list.Add(arg.RawType);
}
Type[] constructorParams = new Type[list.Count];
list.CopyTo(constructorParams);
iter.Constructor =
DefineConstructor(iter.TypeBuilder,
MethodAttributes.Public,
CallingConventions.Standard,
constructorParams);
#if false
iter.Self =
iter.TypeBuilder.DefineField("__self",
boundReceiverType.RawType,
FieldAttributes.Private);
#else
iter.Self =
iter.TypeBuilder.DefineField("__self",
typeBuilder,
FieldAttributes.Private);
#endif
iter.CurrentPosition =
iter.TypeBuilder.DefineField("__currentPosition",
typeof(int),
FieldAttributes.Private);
iter.MoveNext =
DefineMethod(iter.TypeBuilder, "MoveNext",
MethodAttributes.Virtual |
MethodAttributes.HideBySig |
MethodAttributes.Public,
typeManager.BoolType,
iter.MoveNextArguments);
if (!iter.ReturnType.IsNull) {
iter.Current =
iter.TypeBuilder.DefineField("__current",
iter.ReturnType.RawType,
FieldAttributes.Private);
iter.GetCurrent =
DefineMethod(iter.TypeBuilder, "GetCurrent",
MethodAttributes.Virtual |
MethodAttributes.HideBySig |
MethodAttributes.Public,
iter.ReturnType.NodeType,
new TypedNodeList());
}
MethodAttributes attributes =
MethodAttributes.Virtual | MethodAttributes.HideBySig;
switch (iter.Modifier) {
case RoutineModifier.None:
attributes |= MethodAttributes.Public;
break;
case RoutineModifier.Private:
attributes |= MethodAttributes.Private;
break;
}
TypedNodeList creatorArguments =
GetIterCreatorArguments(iter.Arguments);
iter.Creator =
DefineMethod(typeBuilder, creatorName, attributes,
iter.BoundType, creatorArguments);
typeManager.AddIterCreator(iter.Creator);
iter.MethodBuilder =
DefineMethod(typeBuilder, "__iter_" + baseName, attributes,
iter.ReturnType.NodeType,
iter.Arguments);
typeManager.AddBabelName(iter.MethodBuilder, iter.Name);
typeManager.AddIterCreatorName(iter.MethodBuilder, creatorName);
foreach (MethodData m in conformableMethods) {
MethodData abstractCreator = m.IterCreator;
MethodBuilder bridgeMethod =
DefineMethod(typeBuilder,
m.DeclaringType.RawType.FullName + "." +
abstractCreator.Name,
attributes,
abstractCreator.ReturnType,
iter.Arguments);
typeBuilder.DefineMethodOverride(bridgeMethod, m.MethodInfo);
iter.BridgeMethods.Add(bridgeMethod);
}
iterCount++;
}