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; }
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; } }
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); }