/// <summary> /// Unpacks an expression onto a list of declarations. /// </summary> /// <param name="block">Block this takes place in</param> /// <param name="expression">expression to explode</param> /// <param name="declarations">list of declarations to set</param> void UnpackExpression(Block block, Expression expression, DeclarationCollection declarations) { NormalizeIterationStatements.UnpackExpression(CodeBuilder, _currentMethod, block, expression, declarations); }
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), GetProperty(_sourceEnumeratorType, "Current").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))); }