void ProcessBlock (BlockStatement node)
		{
			for (int i = 0; i < node.Statements.Count - 1; i++)
			{
				var matcher = new UsingMatcher(node.Statements[i], node.Statements[i + 1]);
				if (!matcher.Match ())
					continue;

                if (matcher.VariableReference != null)
                {
                    context.MethodContext.RemoveVariable(matcher.VariableReference);
                }
				if (matcher.RemoveExpression)
				{
					node.Statements.RemoveAt(i); // declaration
					node.Statements.RemoveAt(i); // try
					node.AddStatementAt(i, matcher.Using);
				}
				else
				{
					int index = i + (matcher.HasExpression ? 1 : 0);
					node.Statements.RemoveAt(index); // try
					node.AddStatementAt(index, matcher.Using);
				}
				ProcessBlock(matcher.Using.Body);
			}
		}
        public override void VisitBlockStatement(BlockStatement node)
        {
            for (int i = 0; i < node.Statements.Count; i++)
            {
                if (!Match(node.Statements, i))
                    continue;

                // repalce try with lock
                node.Statements.RemoveAt(i);
                node.AddStatementAt(i, Lock);

                //RemoveFlagVariable(i - 1, node, theFlagVariable);

                if (this.lockType == LockType.Simple)
                {
                    node.Statements.RemoveAt(i + 1); //the try
                    node.Statements.RemoveAt(--i); // the second assign
                    node.Statements.RemoveAt(--i); // the first assign
                }
                else // LockType.WithFlag
                {
                    Lock.Body.Statements.RemoveAt(0); // the first assign
                    Lock.Body.Statements.RemoveAt(0); // the second assign
                    Lock.Body.Statements.RemoveAt(0); // the method invoke
                    if(i > 0)
                    {
                        node.Statements.RemoveAt(--i);
                    }
                }
            }

            Visit(node.Statements);
        }
		void ProcessBlock (BlockStatement node)
		{
			for (int i = 0; i < node.Statements.Count - 1; i++)
			{
				ForeachArrayMatcher matcher = new ForeachArrayMatcher(node.Statements[i], node.Statements[i + 1], this.context.MethodContext);
				if (!matcher.Match())
				{
					continue;
				}

				if (CheckForIndexUsages(matcher))
				{
					continue;
				}

				context.MethodContext.RemoveVariable(matcher.Incrementor);
				if (matcher.CurrentVariable != null)
				{
					context.MethodContext.RemoveVariable(matcher.CurrentVariable);
				}

				node.Statements.RemoveAt(i);
				node.Statements.RemoveAt(i);
				node.AddStatementAt(i, matcher.Foreach);
				ProcessBlock(matcher.Foreach.Body);
			}
		}
		private BlockStatement FixSwitchingIf(BlockStatement switchBlock)
		{
			if (switchBlock.Statements.Count < 1)
			{
				// sanity check.
				return switchBlock;
			}
			Statement fixedSwitch = FixSwitchingStatement(switchBlock.Statements[0]);
			switchBlock.Statements.RemoveAt(0);
			switchBlock.AddStatementAt(0, fixedSwitch);
			return switchBlock;
		}
        private void InsertTopLevelParameterAssignments(BlockStatement block)
        {
            for (int i = 0; i < this.context.MethodContext.OutParametersToAssign.Count; i++)
            {
                ParameterDefinition parameter = this.context.MethodContext.OutParametersToAssign[i];
                TypeReference nonPointerType = parameter.ParameterType.IsByReference ? parameter.ParameterType.GetElementType() : parameter.ParameterType;
                UnaryExpression parameterDereference =
                    new UnaryExpression(UnaryOperator.AddressDereference, new ArgumentReferenceExpression(parameter, null), null);

                BinaryExpression assignExpression = new BinaryExpression(BinaryOperator.Assign, parameterDereference,
                    nonPointerType.GetDefaultValueExpression(typeSystem), nonPointerType, typeSystem, null);

                block.AddStatementAt(i, new ExpressionStatement(assignExpression));
            }
        }
 /// <summary>
 /// Adds the starting assignments to the newly introduced flag variables.
 /// </summary>
 /// <param name="body">The body of the method.</param>
 private void AddDefaultAssignmentsToNewConditionalVariables(BlockStatement body)
 {
     foreach (VariableDefinition variable in labelToVariable.Values)
     {
         ///Add assignments for every label variable.
         BinaryExpression defaultAssignment =
             new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(variable, null), GetLiteralExpression(false), typeSystem, null);
         body.AddStatementAt(0, new ExpressionStatement(defaultAssignment));
     }
     if (usedBreakVariable)
     {
         ///Add assignment for the break variable.
         BinaryExpression defaultBreakAssignment =
             new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(breakVariable, null), GetLiteralExpression(false), typeSystem, null);
         body.AddStatementAt(0, new ExpressionStatement(defaultBreakAssignment));
     }
     if (usedContinueVariable)
     {
         ///Add assignment for the continue variable.
         BinaryExpression defaultContinueAssignment =
             new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(continueVariable, null), GetLiteralExpression(false), typeSystem, null);
         body.AddStatementAt(0, new ExpressionStatement(defaultContinueAssignment));
     }
 }
		private void InsertVariableDeclaration(BlockStatement block, int insertIndex, int variableIndex)
		{
			block.AddStatementAt(insertIndex, new ExpressionStatement(new VariableDeclarationExpression(methodVariables[variableIndex], null)));
		}
		private void InsertVariableDeclarationAndAssignment(BlockStatement block, int insertIndex, int variableIndex)
		{
            Expression defaultValueExpression = methodVariables[variableIndex].VariableType.GetDefaultValueExpression(typeSystem);
			
			if (defaultValueExpression == null)
			{
				InsertVariableDeclaration(block, insertIndex, variableIndex);
				return;
			}

			BinaryExpression assignExpression =
                new BinaryExpression(BinaryOperator.Assign, new VariableDeclarationExpression(methodVariables[variableIndex], null),
                    defaultValueExpression, typeSystem, null);
			block.AddStatementAt(insertIndex, new ExpressionStatement(assignExpression));
		}
        /// <summary>
        /// Extracts the condition of the condition statement into new variable. Replaces the condition of the statement with the new variable and inserts 
        /// the assignment statement right before the condition statement.
        /// </summary>
        /// <param name="conditionVar">The variable which should be assigned the condition.</param>
        /// <param name="gotoStatement">The conditional goto.</param>
        /// <param name="containingBlock">The block that contains the conditional goto.</param>
        private void ExtractConditionIntoVariable(VariableReferenceExpression conditionVar, ConditionStatement statement, BlockStatement containingBlock)
        {
            /// Create the statement conditionVariable = originalCondition;
            BinaryExpression conditionAssignment = new BinaryExpression(BinaryOperator.Assign, conditionVar, statement.Condition, typeSystem, null);
            ExpressionStatement assignStatement = new ExpressionStatement(conditionAssignment);

            /// Insert the statement before the original goto statement.
            int gotoIndex = containingBlock.Statements.IndexOf(statement);
            containingBlock.AddStatementAt(gotoIndex, assignStatement);

            /// Update the condition of the goto statement.
            statement.Condition = conditionVar.CloneExpressionOnly();
        }
 /// <summary>
 /// Adds 
 /// <code>
 /// If(<paramref name="conditionVariable"/>)
 /// {
 ///     <paramref name="statement"/>
 /// }
 /// </code>
 /// statement at <paramref name="index"/> in <paramref name="containingBlock"/>
 /// </summary>
 /// <param name="index">The index at which the generated statement must be inserted.</param>
 /// <param name="containingBlock">The block, in which the new statement is inserted.</param>
 /// <param name="statement">The only statement in the then clause.</param>
 /// <param name="conditionVariable">The condition of the if.</param>
 private void AddBreakContinueConditional(int index, BlockStatement containingBlock, Statement statement, VariableReference conditionVariable)
 {
     BlockStatement thenBlock = new BlockStatement();
     thenBlock.AddStatement(statement);
     VariableReferenceExpression ifCondition = new VariableReferenceExpression(conditionVariable, null);
     IfStatement enclosingIfStatement = new IfStatement(ifCondition, thenBlock, null);
     containingBlock.AddStatementAt(index, enclosingIfStatement);
 }
        void ProcessBlock (BlockStatement node)
        {
            for (int i = 0; i < node.Statements.Count - 1; i++)
            {
                FixedStatement @fixed = null;
                List<VariableReference> variableReferences = new List<VariableReference>();

                Statement statement = node.Statements[i];

                @fixed = GetFixedStatement(statement, variableReferences);

                if (@fixed == null)
                {
                    continue;
                }

				foreach (VariableReference variable in variableReferences)
				{
					methodContext.RemoveVariable(variable);
				}
                
                // remove the first statement.
                node.Statements.RemoveAt(i);
                // append the fixed block
                node.AddStatementAt(i, @fixed);

                ExpressionStatement expressionStmt = node.Statements[i + 1] as ExpressionStatement;

                int len = node.Statements.Count;

                VariableReference fixedVariable = null;

                VariableReferenceVisitor varibleVisitor = new VariableReferenceVisitor();
                varibleVisitor.Visit(@fixed.Expression);

                fixedVariable = varibleVisitor.Variable;
               
                for (int stmtIndex = i + 1; stmtIndex < len; stmtIndex++)
                {
                    varibleVisitor = new VariableReferenceVisitor();

                    varibleVisitor.Visit(node.Statements[stmtIndex]);

                    VariableReference variable = varibleVisitor.Variable;

                    if (variable != null && !variables.Contains(variable))
                    {
                        variables.Add(variable);
                    }

                    if (node.Statements[stmtIndex].CodeNodeType == CodeNodeType.ExpressionStatement)
                    {
                        expressionStmt = node.Statements[stmtIndex] as ExpressionStatement;

                        if (variable != null 
                            && variable == fixedVariable
                            && expressionStmt.Expression.CodeNodeType == CodeNodeType.BinaryExpression 
                            && (expressionStmt.Expression as BinaryExpression).IsAssignmentExpression
							&& (expressionStmt.Expression as BinaryExpression).Right.CodeNodeType == CodeNodeType.LiteralExpression
							&& ((expressionStmt.Expression as BinaryExpression).Right as LiteralExpression).Value == null)
                        {
							node.Statements.RemoveAt(stmtIndex);
							stmtIndex--;
							len--;
							break;
						}
                    }
                    @fixed.Body.AddStatement(node.Statements[stmtIndex]);
					node.Statements.RemoveAt(stmtIndex);
					stmtIndex--;
					len--;
                }

				ProcessBlock(@fixed.Body);

                break;
            }
        }
Ejemplo n.º 12
0
		private void RemoveRangeAndInsert(BlockStatement block, int startIndex, int length, Statement newStatement)
		{
			string label = block.Statements[startIndex].Label;
			RemoveRange(block.Statements, startIndex, length);
			newStatement.Label = label;
			if (!string.IsNullOrEmpty(label))
			{
				context.MethodContext.GotoLabels[label] = newStatement;
			}
			block.AddStatementAt(startIndex, newStatement);
		}