void CreateMoveNext()
{
BooMethodBuilder method = _enumerator.AddVirtualMethod("MoveNext", TypeSystemServices.BoolType);
Expression moveNext = CodeBuilder.CreateMethodInvocation(
CodeBuilder.CreateReference((InternalField)_enumeratorField.Entity),
TypeSystemServices.Map(Types.IEnumerator.GetMethod("MoveNext")));
Expression current = CodeBuilder.CreateMethodInvocation(
CodeBuilder.CreateReference((InternalField)_enumeratorField.Entity),
((IProperty)GetMember(_sourceEnumeratorType, "Current", EntityType.Property)).GetGetMethod());
Statement filter = null;
Statement stmt = null;
Block outerBlock = null;
Block innerBlock = null;
if (null == _generator.Filter)
{
IfStatement istmt = new IfStatement(moveNext, new Block(), null);
outerBlock = innerBlock = istmt.TrueBlock;
stmt = istmt;
}
else
{
WhileStatement wstmt = new WhileStatement(moveNext);
outerBlock = wstmt.Block;
if (StatementModifierType.If == _generator.Filter.Type)
{
IfStatement ifstmt = new IfStatement(_generator.Filter.Condition, new Block(), null);
innerBlock = ifstmt.TrueBlock;
filter = ifstmt;
}
else
{
UnlessStatement ustmt = new UnlessStatement(_generator.Filter.Condition);
innerBlock = ustmt.Block;
filter = ustmt;
}
stmt = wstmt;
}
DeclarationCollection declarations = _generator.Declarations;
if (declarations.Count > 1)
{
NormalizeIterationStatements.UnpackExpression(CodeBuilder,
method.Method,
outerBlock,
current,
declarations);
foreach (Declaration declaration in declarations)
{
method.Locals.Add(((InternalLocal)declaration.Entity).Local);
}
}
else
{
InternalLocal local = (InternalLocal)declarations[0].Entity;
method.Locals.Add(local.Local);
outerBlock.Add(CodeBuilder.CreateAssignment(
CodeBuilder.CreateReference(local),
current));
}
if (null != filter)
{
outerBlock.Add(filter);
}
innerBlock.Add(CodeBuilder.CreateAssignment(
CodeBuilder.CreateReference((InternalField)_current.Entity),
_generator.Expression));
innerBlock.Add(new ReturnStatement(new BoolLiteralExpression(true)));
method.Body.Add(stmt);
method.Body.Add(new ReturnStatement(new BoolLiteralExpression(false)));
}