void CreateMoveNext()
{
Method generator = _generator.Method;
BooMethodBuilder methodBuilder = _enumerator.AddVirtualMethod("MoveNext", TypeSystemServices.BoolType);
methodBuilder.Method.LexicalInfo = generator.LexicalInfo;
_moveNext = methodBuilder.Entity;
foreach (Local local in generator.Locals)
{
InternalLocal entity = (InternalLocal)local.Entity;
Field field = _enumerator.AddInternalField("$" + entity.Name + "$" + _context.AllocIndex(), entity.Type);
_mapping[entity] = field.Entity;
}
generator.Locals.Clear();
foreach (ParameterDeclaration parameter in generator.Parameters)
{
InternalParameter entity = (InternalParameter)parameter.Entity;
if (entity.IsUsed)
{
Field field = DeclareFieldInitializedFromConstructorParameter(_enumerator, _enumeratorConstructor,
entity.Name,
entity.Type);
_mapping[entity] = field.Entity;
}
}
methodBuilder.Body.Add(CreateLabel(generator));
// Visit() needs to know the number of the finished state
_finishedStateNumber = _labels.Count;
LabelStatement finishedLabel = CreateLabel(generator);
methodBuilder.Body.Add(generator.Body);
generator.Body.Clear();
Visit(methodBuilder.Body);
methodBuilder.Body.Add(CreateYieldInvocation(null, _finishedStateNumber));
methodBuilder.Body.Add(finishedLabel);
methodBuilder.Body.Insert(0,
CodeBuilder.CreateSwitch(
this.LexicalInfo,
CodeBuilder.CreateMemberReference(_state),
_labels));
// if the method contains converted try statements, put it in a try/failure block
if (_convertedTryStatements.Count > 0)
{
IMethod dispose = CreateDisposeMethod();
TryStatement tryFailure = new TryStatement();
tryFailure.ProtectedBlock.Add(methodBuilder.Body);
tryFailure.FailureBlock = new Block();
tryFailure.FailureBlock.Add(CallMethodOnSelf(dispose));
methodBuilder.Body.Clear();
methodBuilder.Body.Add(tryFailure);
}
}