protected virtual void SetupIter(IterCallExpression iter,
MethodData method,
TypeData receiverType)
{
if (!method.MethodInfo.IsPublic &&
currentClass.TypeData != receiverType) {
report.Error(iter.Location,
"cannot call private iterator {0}",
iter.Name);
return;
}
iter.IsBuiltin = method.IsBuiltin;
MethodData creator = method.IterCreator;
iter.Method = creator.MethodInfo;
iter.NodeType = method.ReturnType;
if (iter.Receiver == null &&
(iter.IsBuiltin || !method.MethodInfo.IsStatic)) {
iter.Receiver = new VoidExpression(iter.Location);
iter.Receiver.NodeType = receiverType;
}
TypeData iterType = creator.ReturnType;
string localName = getTemporallyName();
iter.Local = localVariableStack.AddLocal(localName,
iterType);
iter.CreatorArguments = new TypedNodeList();
TypedNodeList moveNextArguments = new TypedNodeList();
ModalExpression receiver =
new ModalExpression(ArgumentMode.In,
(Expression) iter.Receiver.Clone(),
iter.Receiver.Location);
ParameterInfo[] parameters =
typeManager.GetParameters(method.MethodInfo);
int i;
if (iter.IsBuiltin)
i = 1;
else
i = 0;
foreach (ModalExpression arg in iter.Arguments) {
ParameterInfo param = parameters[i++];
if (arg.NodeType == null) // void expression
arg.NodeType = typeManager.GetTypeData(param.ParameterType);
ArgumentMode mode = typeManager.GetArgumentMode(param);
if (mode == ArgumentMode.Once) {
ModalExpression me = (ModalExpression) arg.Clone();
me.Mode = ArgumentMode.In;
iter.CreatorArguments.Append(me);
}
else {
moveNextArguments.Append((ModalExpression) arg.Clone());
}
}
LocalExpression moveNextReceiver =
new LocalExpression(iter.Local.Name, iter.Location);
iter.MoveNext = new CallExpression(moveNextReceiver,
"MoveNext",
moveNextArguments,
iter.Location);
iter.MoveNext.Accept(this);
if (!iter.NodeType.IsVoid) {
LocalExpression getCurrentReceiver =
new LocalExpression(iter.Local.Name, iter.Location);
iter.GetCurrent = new CallExpression(getCurrentReceiver,
"GetCurrent",
new TypedNodeList(),
iter.Location);
iter.GetCurrent.Accept(this);
}
}