Пример #1
0
        public override SyntaxList <StatementSyntax> VisitForBlock(VBSyntax.ForBlockSyntax node)
        {
            var stmt = node.ForStatement;
            ExpressionSyntax          startValue  = (ExpressionSyntax)stmt.FromValue.Accept(_expressionVisitor);
            VariableDeclarationSyntax declaration = null;
            ExpressionSyntax          id;
            var controlVarOp   = _semanticModel.GetOperation(stmt.ControlVariable) as IVariableDeclaratorOperation;
            var controlVarType = controlVarOp?.Symbol.Type;
            var initializers   = new List <ExpressionSyntax>();

            if (stmt.ControlVariable is VBSyntax.VariableDeclaratorSyntax)
            {
                var v = (VBSyntax.VariableDeclaratorSyntax)stmt.ControlVariable;
                declaration = CommonConversions.SplitVariableDeclarations(v).Values.Single();
                declaration = declaration.WithVariables(SyntaxFactory.SingletonSeparatedList(declaration.Variables[0].WithInitializer(SyntaxFactory.EqualsValueClause(startValue))));
                id          = SyntaxFactory.IdentifierName(declaration.Variables[0].Identifier);
            }
            else
            {
                id = (ExpressionSyntax)stmt.ControlVariable.Accept(_expressionVisitor);
                var controlVarSymbol = controlVarOp?.Symbol;
                if (controlVarSymbol != null && controlVarSymbol.DeclaringSyntaxReferences.Any(r => r.Span.OverlapsWith(stmt.ControlVariable.Span)))
                {
                    declaration = CommonConversions.CreateVariableDeclarationAndAssignment(controlVarSymbol.Name, startValue, CommonConversions.GetTypeSyntax(controlVarType));
                }
                else
                {
                    startValue = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, id, startValue);
                    initializers.Add(startValue);
                }
            }

            var step = (ExpressionSyntax)stmt.StepClause?.StepValue.Accept(_expressionVisitor);
            PrefixUnaryExpressionSyntax value = step.SkipParens() as PrefixUnaryExpressionSyntax;
            ExpressionSyntax            condition;

            // In Visual Basic, the To expression is only evaluated once, but in C# will be evaluated every loop.
            // If it could evaluate differently or has side effects, it must be extracted as a variable
            var preLoopStatements = new List <SyntaxNode>();
            var csToValue         = (ExpressionSyntax)stmt.ToValue.Accept(_expressionVisitor);

            if (!_semanticModel.GetConstantValue(stmt.ToValue).HasValue)
            {
                var loopToVariableName = GetUniqueVariableNameInScope(node, "loopTo");
                var toValueType        = _semanticModel.GetTypeInfo(stmt.ToValue).ConvertedType;
                var toVariableId       = SyntaxFactory.IdentifierName(loopToVariableName);
                if (controlVarType?.Equals(toValueType) == true && declaration != null)
                {
                    var loopToAssignment = CommonConversions.CreateVariableDeclarator(loopToVariableName, csToValue);
                    declaration = declaration.AddVariables(loopToAssignment);
                }
                else
                {
                    var loopEndDeclaration = SyntaxFactory.LocalDeclarationStatement(
                        CommonConversions.CreateVariableDeclarationAndAssignment(loopToVariableName, csToValue));
                    // Does not do anything about porting newline trivia upwards to maintain spacing above the loop
                    preLoopStatements.Add(loopEndDeclaration);
                }

                csToValue = toVariableId;
            }
            ;

            if (value == null)
            {
                condition = SyntaxFactory.BinaryExpression(SyntaxKind.LessThanOrEqualExpression, id, csToValue);
            }
            else
            {
                condition = SyntaxFactory.BinaryExpression(SyntaxKind.GreaterThanOrEqualExpression, id, csToValue);
            }
            if (step == null)
            {
                step = SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, id);
            }
            else
            {
                step = SyntaxFactory.AssignmentExpression(SyntaxKind.AddAssignmentExpression, id, step);
            }
            var block = SyntaxFactory.Block(node.Statements.SelectMany(s => s.Accept(CommentConvertingVisitor)));
            var forStatementSyntax = SyntaxFactory.ForStatement(
                declaration,
                SyntaxFactory.SeparatedList(initializers),
                condition,
                SyntaxFactory.SingletonSeparatedList(step),
                block.UnpackNonNestedBlock());

            return(SyntaxFactory.List(preLoopStatements.Concat(new[] { forStatementSyntax })));
        }