public Statement FixToSwitch(IfStatement node, VariableReferenceExpression stringVariable, VariableReferenceExpression intVariable)
		{
			/// The checks in the matcher ensured that the first statement in <paramref name="node"/> is an if statement, and
			/// that the dictionary is filled inside it's Then body.
			/// 
			this.theIntVariable = intVariable;
			this.theStringVariable = stringVariable;
			if (node.Then.Statements.Count != 2)
			{
				// sanity check;
				return node;
			}
			if (!(node.Then.Statements[0] is IfStatement) || !(node.Then.Statements[1] is IfStatement))
			{
				/// sanity checks
				return node;
			}
			FillValueDictionary((node.Then.Statements[0] as IfStatement).Then);
			BlockStatement result = FixSwitchingIf((node.Then.Statements[1] as IfStatement).Then);

			node.Then.Statements.Clear();
			node.Then = result;

			return node;
		}
 public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
 {
     if (node.Variable.Resolve() == variable)
     {
         this.searchResult = UsageFinderSearchResult.Used;
     }
 }
		public ArrayVariableReferenceExpression(VariableReferenceExpression variable, TypeReference arrayType, ExpressionCollection dimensions, bool hasInitializer, IEnumerable<Instruction> instructions) 
			: base(instructions)
		{
			this.Variable = variable;
			this.ArrayType = arrayType;
			this.Dimensions = dimensions;
			this.HasInitializer = hasInitializer;
		}
Example #4
0
        public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
        	if (node.Variable != variable)
				return;

			Match = true;
			Continue = false;
		}
 public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
 {
     if (node.Variable == variable)
     {
         found = true;
         return;
     }
     base.VisitVariableReferenceExpression(node);
 }
			public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
			{
				if (node.Variable == theVariable)
				{
					this.Used = true;
					return;
				}
				base.VisitVariableReferenceExpression(node);
			}
        public override ICodeNode VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
            VariableDefinition variable = (VariableDefinition)node.Variable;

            if (!TryDiscardVariable(variable))
            {
                return node;
            }

            return new VariableDeclarationExpression(variable, node.UnderlyingSameMethodInstructions);
        }
		public bool TryMatch(IfStatement node)
		{
			this.DictionaryField = null;
			this.StringVariable = null;
			this.IntVariable = null;
			if (IsNullCheck(node.Condition) || node.Else == null)
			{
				if (CheckOuterIfBody(node.Then))
				{
					return true;
				}
			}
			return false;
		}
        public override ICodeNode VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
            if (this.variableToReplacingExpressionMap.ContainsKey(node.Variable))
            {
                if (this.variablesToNotInline.Contains(node.Variable))
                {
                    this.initializationsToFix.Add(node.Variable, this.initializationsToRemove[node.Variable]);
                    this.initializationsToRemove.Remove(node.Variable);

                    return node;
                }
            }

            return base.VisitVariableReferenceExpression(node);
        }
        public override ICodeNode VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
            if (status == InliningResult.Abort)
            {
                //sanity check
                throw new Exception("Invalid state");
            }

            if (node.Variable.Resolve() == variableDef)
            {
                status = InliningResult.Success;
                return GetNewValue(node);
            }
            return node;
        }
        public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
			if (currentForIndeces.Count > 0)
			{
				var currentForIndex = currentForIndeces.Peek();
				if (currentForIndex == node.Variable)
				{
					if (!currentForIndecesUsed.Peek())
					{
						currentForIndecesUsed.Pop();
						currentForIndecesUsed.Push(true);
					}
				}
			}
			base.VisitVariableReferenceExpression(node);
		}
        protected override ICodeNode GetIfSubstitution(IfStatement node)
        {
            BinaryExpression condition = node.Condition as BinaryExpression;
            if (condition.Left.CodeNodeType != CodeNodeType.FieldReferenceExpression)
            {
                return null;
            }

            FieldReferenceExpression fieldReference = condition.Left as FieldReferenceExpression;
            FieldDefinition fieldDefinition = fieldReference.Field.Resolve();
            if (!this.fieldToReplacingExpressionMap.ContainsKey(fieldDefinition))
            {
                throw new Exception("Caching field not found.");
            }

            VariableDefinition newVariable = new VariableDefinition(fieldDefinition.FieldType);
            VariableReferenceExpression newVariableReference = new VariableReferenceExpression(newVariable, null);
            BinaryExpression newAssignment = new BinaryExpression(BinaryOperator.Assign, newVariableReference, this.fieldToReplacingExpressionMap[fieldDefinition],
                                                                  this.context.MethodContext.Method.Module.TypeSystem, null);
            ExpressionStatement newStatement = new ExpressionStatement(newAssignment);

            this.initializationsToRemove.Add(newVariable, newStatement);

            this.variableToReplacingExpressionMap.Add(newVariable, this.fieldToReplacingExpressionMap[fieldDefinition]);
            this.fieldToReplacingExpressionMap[fieldDefinition] = newVariableReference;

            this.context.MethodContext.Variables.Add(newVariable);
            this.context.MethodContext.VariablesToRename.Add(newVariable);

            return newStatement;
        }
 public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
 {
     if (node.Variable == variable)
     {
         this.isUsed = true;
     }
 }
Example #14
0
 public IntoClause(VariableReferenceExpression identifier, IEnumerable <Instruction> instructions)
 {
     base(instructions);
     this.set_Identifier(identifier);
     return;
 }
		public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
		{
			if (processStep == ProcessStep.Replace)
				return;

			var state = states.Peek();
			if (ContainsKey(node.Variable))
			{
				ChangeVariableState(state, node);
			}
			else
			{
				VariableState variableState = GetInitialVariableState(state);
				var variableStateAndExpression = new VariableStateAndExpression(node.Variable, variableState);
                if (state == Step.Assign)
                {
                    variableStateAndExpression.NumberOfTimesAssigned++;
                }
				variables.Add(variableStateAndExpression);
			}
			base.VisitVariableReferenceExpression(node);

            this.currentVariable = node.Variable;
		}
 public IntoClause(VariableReferenceExpression identifier, IEnumerable <Instruction> instructions) : base(instructions)
 {
     this.Identifier = identifier;
 }
        /// <summary>
        /// Performs a move out operation on the goto statement. For more information see
        /// Chapter 2.2.1 "Outward-movement Transformations"
        /// </summary>
        /// <param name="gotoStatement"></param>
        /// <param name="label"></param>
        private void MoveOut(IfStatement gotoStatement, string label)
        {
            /// Preprocessing.
            BlockStatement containingBlock = gotoStatement.Parent as BlockStatement;
            BlockStatement outerBlock = GetOuterBlock(containingBlock);
            VariableReferenceExpression conditionVar = new VariableReferenceExpression(GetLabelVariable(label), null);

            ExtractConditionIntoVariable(conditionVar.CloneExpressionOnly() as VariableReferenceExpression, gotoStatement, containingBlock);

            Statement oldEnclosingStatement = containingBlock.Parent;
            if (oldEnclosingStatement is SwitchCase)
            {
                oldEnclosingStatement = oldEnclosingStatement.Parent;
            }
            if (containingBlock.Parent is SwitchCase || containingBlock.Parent is WhileStatement || containingBlock.Parent is DoWhileStatement || containingBlock.Parent is ForStatement
                || containingBlock.Parent is ForEachStatement)
            {
                /// Then we can exit using break.
                /// Create the if - break.
                BlockStatement thenBlock = new BlockStatement();
                thenBlock.AddStatement(new BreakStatement(null));  //might have to keep track of brakes
                IfStatement breakIf = new IfStatement(conditionVar.CloneExpressionOnly(), thenBlock, null);

                /// Replace the original goto
                int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
                containingBlock.Statements.Remove(gotoStatement);
                containingBlock.AddStatementAt(gotoIndex, breakIf);
            }
            else if (containingBlock.Parent is IfStatement || containingBlock.Parent is TryStatement || containingBlock.Parent is IfElseIfStatement)
            {
                /// Then we can exit via introducing another condition.
                int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
                int index = gotoIndex + 1;
                BlockStatement thenBlock = new BlockStatement();
                while (index < containingBlock.Statements.Count)
                {
                    thenBlock.AddStatement(containingBlock.Statements[index]);
                    containingBlock.Statements.RemoveAt(index);
                }
                UnaryExpression condition = new UnaryExpression(UnaryOperator.LogicalNot, conditionVar.CloneExpressionOnly(), null);
                IfStatement innerIf = new IfStatement(condition, thenBlock, null);

                /// At this point the goto statement should be the last one in the block.
                /// Simply replace it with the new if.
                containingBlock.Statements.Remove(gotoStatement);
                /// If the then block is empty, the if should not be added.
                if (innerIf.Then.Statements.Count != 0)
                {
                    containingBlock.AddStatement(innerIf);
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("Goto statement can not leave this parent construct.");
            }

            /// Add the goto statement after the construct.
            /// The goto statement shoud be detached from the AST at this point.
            outerBlock.AddStatementAt(outerBlock.Statements.IndexOf(oldEnclosingStatement) + 1, gotoStatement);
        }
        /// <summary>
        /// Contains the logic for moving a  goto inside the case of switch statement. For more information 
        /// see Chapter "2.2.2 Inward-movement Transformations : Moving a goto into a switch statement" from
        /// <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>.
        /// </summary>
        /// <param name="gotoStatement">The goto statement to be moved in.</param>
        /// <param name="switchCase">The switch case that contains the target of the goto statement.</param>
        /// <param name="label">The label of the target.</param>
        private void MoveInCase(IfStatement gotoStatement, SwitchCase switchCase, string label)
        {
            VariableReferenceExpression conditionVariable = new VariableReferenceExpression(GetLabelVariable(label), null);
            BlockStatement containingBlock = GetOuterBlock(gotoStatement);
            SwitchStatement switchStatement = switchCase.Parent as SwitchStatement;

            int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
            int switchIndex = containingBlock.Statements.IndexOf(switchStatement);

            /// Generate variable and extract the switch condition
            string switchVariableName = "switch" + switchStatement.ConditionBlock.First.Offset;
            TypeReference switchVariableType = GetSwitchType(switchStatement);
            VariableDefinition switchVariable = new VariableDefinition(switchVariableName, switchVariableType);
            switchVariables.Add(switchVariable);
            VariableReferenceExpression switchVarEx = new VariableReferenceExpression(switchVariable, null);
            ExtractConditionIntoVariable(switchVarEx, switchStatement, containingBlock);

            BlockStatement thenBlock = CollectStatements(gotoIndex + 1, switchIndex + 1, containingBlock);

            BlockStatement elseBlock = new BlockStatement();

            /// Adds swCond = caseCond; in the last part of else.
            BinaryExpression assignSwitchVariable = new BinaryExpression(BinaryOperator.Assign, switchVarEx.CloneExpressionOnly(), GetCaseConditionExpression(switchCase), typeSystem, null);
            elseBlock.AddStatement(new ExpressionStatement(assignSwitchVariable));

            IfStatement precedingIf = new IfStatement(new UnaryExpression(UnaryOperator.LogicalNot, conditionVariable, null), thenBlock, elseBlock);

            /// Attach new if and move the goto conditional.
            /// Attach it only if the then block is not empty.
            if (precedingIf.Then.Statements.Count != 0)
            {
                containingBlock.AddStatementAt(gotoIndex, precedingIf);
            }
            containingBlock.Statements.Remove(gotoStatement);
            switchCase.Body.AddStatementAt(0, gotoStatement);
        }
        /// <summary>
        /// Performs a move-in transformation as described in Chapter 2.2.2 in <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>.
        /// </summary>
        /// <param name="gotoStatement">The goto statement to be moved in.</param>
        /// <param name="targetStatement">The statement that the goto will move in.</param>
        /// <param name="label">The target label.</param>
        private void MoveIn(IfStatement gotoStatement, Statement targetStatement, string label)
        {
            /// Preprocessing.
            BlockStatement containingBlock = gotoStatement.Parent as BlockStatement;
            VariableReferenceExpression conditionVar = new VariableReferenceExpression(GetLabelVariable(label), null);

            /// Create the statement conditionVariable = originalCondition;
            /// Add the assigning statement before gotoStatement and replace originalCondition with conditionVariable
            ExtractConditionIntoVariable(conditionVar.CloneExpressionOnly() as VariableReferenceExpression, gotoStatement, containingBlock);

            /// Collect the statements between the goto jump and the target statement.
            int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
            int targetIndex = containingBlock.Statements.IndexOf(targetStatement);
            BlockStatement thenBlock = CollectStatements(gotoIndex + 1, targetIndex, containingBlock);

            /// Create the new if.
            IfStatement outerIfStatement =
                new IfStatement(new UnaryExpression(UnaryOperator.LogicalNot, conditionVar.CloneExpressionOnly(), null), thenBlock, null);

            /// Replace the old goto with the new if statement.
            if (outerIfStatement.Then.Statements.Count > 0)
            {
                containingBlock.AddStatementAt(gotoIndex, outerIfStatement);
            }
            containingBlock.Statements.Remove(gotoStatement);

            /// At this point the original goto statement is completely detached from the AST. It must be reattached as the first statement in the target.
            if (targetStatement is DoWhileStatement)
            {
                /// Loops with more than one entry can be created only by this step, so the do-while loops is the only one
                /// that must be considered.
                (targetStatement as DoWhileStatement).Body.AddStatementAt(0, gotoStatement);
            }
            else if (targetStatement is IfStatement)
            {
                /// If statements with more than one entry to then/else blocks can be created only by this step, so that's why
                /// the only case that must be considered is the case when the target is in the then block.
                IfStatement targetIf = targetStatement as IfStatement;
                targetIf.Condition = UpdateCondition(targetIf.Condition, conditionVar.CloneExpressionOnly() as VariableReferenceExpression); /// This greatly depends on the short-circut evaluation.
                targetIf.Then.AddStatementAt(0, gotoStatement);
            }
            else if (targetStatement is SwitchCase)
            {
                MoveInCase(gotoStatement, targetStatement as SwitchCase, label);
            }
            else if (targetStatement is WhileStatement)
            {
                /// This case should not be reachable.
                WhileStatement @while = targetStatement as WhileStatement;
                @while.Body.AddStatementAt(0, gotoStatement);
                @while.Condition = UpdateCondition(@while.Condition, conditionVar.CloneExpressionOnly() as VariableReferenceExpression);
            }
            else
            {
                throw new NotSupportedException("Unsupported target statement for goto jump.");
            }
        }
        /// <summary>
        /// Performs lifting operation on the goto statement. For more information, see
        /// Chapter "2.2.3 Goto-lifting Transformation" in <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>.
        /// </summary>
        /// <param name="gotoStatement">The goto to be lifted.</param>
        /// <param name="labelContainingStatement">The statement, containing the target of the goto.</param>
        /// <param name="label">The label of the target.</param>
        private void LiftGoto(IfStatement gotoStatement, Statement labelContainingStatement, string label)
        {
            BlockStatement containingBlock = GetOuterBlock(gotoStatement);
            VariableReferenceExpression variableEx = new VariableReferenceExpression(GetLabelVariable(label), null);

            ExtractConditionIntoVariable(variableEx, gotoStatement, containingBlock);

            /// Extract the do-while loop body from the current block
            int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
            int labelIndex = containingBlock.Statements.IndexOf(labelContainingStatement);
            BlockStatement loopBody = CollectStatements(labelIndex, gotoIndex, containingBlock);

            /// Add the goto statement as the first one in the new do-while loop
            loopBody.AddStatementAt(0, gotoStatement);

            /// Remove the goto from its old parent block and attach the do-while loop on its place
            gotoIndex = containingBlock.Statements.IndexOf(gotoStatement);
            containingBlock.Statements.Remove(gotoStatement);
            DoWhileStatement doWhileLoop = new DoWhileStatement(gotoStatement.Condition.CloneExpressionOnly(), loopBody);
            containingBlock.AddStatementAt(gotoIndex, doWhileLoop);
        }
        /// <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();
        }
        public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
            VariableDefinition variable = node.Variable.Resolve();
            if (!methodContext.VariableDefinitionToNameMap.ContainsKey(variable))
            {
                methodContext.VariableDefinitionToNameMap[variable] = variable.Name;
            }

            if (state == State.SearchForPossibleNames)
            {
                SuggestNameForVariable(variable);
            }

            if (state == State.RenameVariables && methodContext.UndeclaredLinqVariables.Remove(variable))
            {
                TryRenameVariable(variable);
            }

            base.VisitVariableReferenceExpression(node);
        }
        public override Expression Clone()
        {
            VariableReferenceExpression result = new VariableReferenceExpression(Variable, instructions);

            return(result);
        }
		private void ChangeVariableState(Step state, VariableReferenceExpression node)
		{
			VariableStateAndExpression variableStateAndExpression = GetValue(node.Variable);
			
            if ((state == Step.Expression) 
                && (variableStateAndExpression.VariableState != VariableState.Other)
                && variableStateAndExpression.NumberOfTimesAssigned <= 1)
			{
				variableStateAndExpression.VariableState = VariableState.Condition;
            }
			else if (state == Step.Assign)
			{
                if (variableStateAndExpression.VariableState == VariableState.Condition)
                    variableStateAndExpression.VariableState = VariableState.Assign | VariableState.Condition;
                else
                {
                    variableStateAndExpression.VariableState = VariableState.Assign;
                    variableStateAndExpression.NumberOfTimesAssigned++;
                }
		 	}
			else
			{
				variableStateAndExpression.VariableState = VariableState.Other;
			}
		}
 public IntoClause(VariableReferenceExpression identifier, IEnumerable<Instruction> instructions) : base(instructions)
 {
     this.Identifier = identifier;
 }
 protected override ICodeNode GetNewValue(VariableReferenceExpression node)
 {
     return value.CloneAndAttachInstructions(node.UnderlyingSameMethodInstructions);
 }
 public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
 {
     if (node.Variable == oldVariable)
     {
         node.Variable = newVariable;
     }
 }
        public override ICodeNode VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
            if(this.conversionDepth > 0)
            {
                Expression result;
                if (this.variableToValueMap.TryGetValue(node.Variable, out result))
                {
                    usedVariables.Add(node.Variable);
                    return Visit(result.CloneExpressionOnly());
                }

                this.failure = !this.context.MethodContext.ClosureVariableToFieldValue.ContainsKey(node.Variable);
            }
            return base.VisitVariableReferenceExpression(node);
        }
 public LetClause(VariableReferenceExpression identifier, Expression expression, IEnumerable <Instruction> instructions) : base(instructions)
 {
     this.Identifier = identifier;
     this.Expression = expression;
 }
        public override Expression CloneExpressionOnly()
        {
            VariableReferenceExpression result = new VariableReferenceExpression(Variable, null);

            return(result);
        }
        public override ICodeNode VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
            Expression variableValue;
            if (variablesToRemove.TryGetValue(node.Variable, out variableValue))
            {
                return variableValue.CloneExpressionOnlyAndAttachInstructions(node.UnderlyingSameMethodInstructions);
            }

            return base.VisitVariableReferenceExpression(node);
        }
		public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
		{
			Write(GetVariableName(node.Variable));
		}
		public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
		{
			referenceToDeclarationStatementMap.Remove(node.Variable);
			bannedVariables.Add(node.Variable);
		}
            public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
            {
                if (node.Variable == enumerator)
                {
                    IsEnumeratorUsed = true;
                }

                base.VisitVariableReferenceExpression(node);
            }
        public override void VisitVariableReferenceExpression(VariableReferenceExpression node)
        {
			if (!variableReferences.ContainsKey(node.Variable))
			{
				variableReferences.Add(node.Variable, (codeNodeTypes.Peek() == CodeNodeType.BinaryExpression) && inLambdaCount == 0);
			}
			base.VisitVariableReferenceExpression(node);
		}