Boo.Lang.Compiler.Steps.OptimizeIterationStatements.CheckForItemInArrayLoop C# (CSharp) Метод

CheckForItemInArrayLoop() приватный Метод

Optimize the for item in array construct
private CheckForItemInArrayLoop ( Boo.Lang.Compiler.Ast.ForStatement node ) : void
node Boo.Lang.Compiler.Ast.ForStatement the for statement to check
Результат void
        private void CheckForItemInArrayLoop(ForStatement node)
        {
            ArrayType enumeratorType = GetExpressionType(node.Iterator) as ArrayType;
            if (enumeratorType == null || enumeratorType.GetArrayRank() > 1) return;
            IType elementType = enumeratorType.GetElementType();
            if (elementType is InternalCallableType) return;

            Block body = new Block(node.LexicalInfo);

            InternalLocal indexVariable = DeclareTempLocal(TypeSystemServices.IntType);
            Expression indexReference = CodeBuilder.CreateReference(indexVariable);

            // __num = 0
            body.Add(
                CodeBuilder.CreateAssignment(
                    indexReference,
                    CodeBuilder.CreateIntegerLiteral(0)));

            InternalLocal arrayVar = DeclareTempLocal(node.Iterator.ExpressionType);
            ReferenceExpression arrayRef = CodeBuilder.CreateReference(arrayVar);

            // __arr = <arr>
            body.Add(
                CodeBuilder.CreateAssignment(
                    arrayRef,
                    node.Iterator));

            InternalLocal endVar = CodeBuilder.DeclareTempLocal(
                            _currentMethod,
                            TypeSystemServices.IntType);
            ReferenceExpression endRef = CodeBuilder.CreateReference(endVar);

            // __end = __arr.Length
            body.Add(
                CodeBuilder.CreateAssignment(
                    node.Iterator.LexicalInfo,
                    endRef,
                    CodeBuilder.CreateMethodInvocation(
                            arrayRef,
                            Array_get_Length)));

            // while __num < __end:
            WhileStatement ws = new WhileStatement(node.LexicalInfo);

            ws.Condition = CodeBuilder.CreateBoundBinaryExpression(
                    TypeSystemServices.BoolType,
                    BinaryOperatorType.LessThan,
                    indexReference,
                    endRef);

            if (1 == node.Declarations.Count)
            {
                IEntity loopVariable = node.Declarations[0].Entity;
                node.Block.ReplaceNodes(
                    new NodePredicate(new EntityPredicate(loopVariable).Matches),
                    CreateRawArraySlicing(arrayRef, indexReference, elementType));
            }
            else
            {
                //  alpha, bravo, charlie = arr[__num]
                UnpackExpression(
                    ws.Block,
                    CreateRawArraySlicing(arrayRef, indexReference, elementType),
                    node.Declarations);
            }

            //	<block>
            ws.Block.Add(node.Block);

            FixContinueStatements(node, ws);

            //  __num += 1
            BinaryExpression assignment = CodeBuilder.CreateAssignment(
                indexReference,
                CodeBuilder.CreateBoundBinaryExpression(
                    TypeSystemServices.IntType,
                    BinaryOperatorType.Addition,
                    indexReference,
                    CodeBuilder.CreateIntegerLiteral(1)));
            AstAnnotations.MarkUnchecked(assignment);

            ws.Block.Add(assignment);
            ws.OrBlock = node.OrBlock;
            ws.ThenBlock = node.ThenBlock;
            body.Add(ws);
            ReplaceCurrentNode(body);
        }