public override void VisitExpressionStatement(ExpressionStatement node) { VariableReference theVariableReference = null; if (node.Expression.CodeNodeType == CodeNodeType.BinaryExpression && (node.Expression as BinaryExpression).IsAssignmentExpression) { Expression left = (node.Expression as BinaryExpression).Left; if (left.CodeNodeType == CodeNodeType.VariableReferenceExpression) { theVariableReference = (left as VariableReferenceExpression).Variable; } else if (left.CodeNodeType == CodeNodeType.VariableDeclarationExpression) { theVariableReference = (left as VariableDeclarationExpression).Variable; } } if (theVariableReference != null && node.Parent.CodeNodeType == CodeNodeType.BlockStatement && !bannedVariables.Contains(theVariableReference)) { if (!referenceToDeclarationStatementMap.Remove(theVariableReference)) { referenceToDeclarationStatementMap[theVariableReference] = node; } else { bannedVariables.Add(theVariableReference); } base.Visit((node.Expression as BinaryExpression).Right); return; } base.Visit(node.Expression); }
public override void VisitExpressionStatement(ExpressionStatement node) { if (!node.IsAssignmentStatement()) { return; } BinaryExpression assignExpression = node.Expression as BinaryExpression; if(assignExpression.Left.CodeNodeType != CodeNodeType.VariableReferenceExpression || assignExpression.Right.CodeNodeType != CodeNodeType.FieldReferenceExpression) { return; } FieldReferenceExpression targetFieldRefExpression = assignExpression.Right as FieldReferenceExpression; if(targetFieldRefExpression.Target == null || targetFieldRefExpression.Target.CodeNodeType != CodeNodeType.FieldReferenceExpression || targetFieldRefExpression.Field.Name != "Target") { return; } FieldDefinition callSiteField = (targetFieldRefExpression.Target as FieldReferenceExpression).Field.Resolve(); CallSiteInfo callSiteInfo; if(callSiteField == null || !fieldToCallSiteInfoMap.TryGetValue(callSiteField, out callSiteInfo)) { return; } variableToCallSiteInfoMap.Add((assignExpression.Left as VariableReferenceExpression).Variable, callSiteInfo); statementsToRemove.Add(node); }
public override ICodeNode VisitExpressionStatement(ExpressionStatement node) { if (CheckVariableInitialization(node)) { return node; } return base.VisitExpressionStatement(node); }
//x = cond ? y : z; // //== // //if(cond) //{ // x = y; //} //else //{ // x = z; //} // //x - phi variable //y, z - expressions public bool TryMatchInternal(IfStatement theIfStatement, out Statement result) { result = null; if (theIfStatement == null) { return false; } VariableReference xVariableReference = null; VariableReference x1VariableReference = null; Expression yExpressionValue; Expression zExpressionValue; if (theIfStatement.Else == null || theIfStatement.Then.Statements.Count != 1 || theIfStatement.Else.Statements.Count != 1 || theIfStatement.Then.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement || theIfStatement.Else.Statements[0].CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } BinaryExpression thenAssignExpression = (theIfStatement.Then.Statements[0] as ExpressionStatement).Expression as BinaryExpression; BinaryExpression elseAssignExpression = (theIfStatement.Else.Statements[0] as ExpressionStatement).Expression as BinaryExpression; if (!IsAssignToVariableExpression(thenAssignExpression, out x1VariableReference) || !IsAssignToVariableExpression(elseAssignExpression, out xVariableReference)) { return false; } if (xVariableReference != x1VariableReference) { return false; } if (!ShouldInlineExpressions(thenAssignExpression, elseAssignExpression)) { /// Although correct syntax, nesting ternary expressions makes the code very unreadable. return false; } yExpressionValue = GetRightExpressionMapped(thenAssignExpression); zExpressionValue = GetRightExpressionMapped(elseAssignExpression); ConditionExpression ternaryConditionExpression = new ConditionExpression(theIfStatement.Condition, yExpressionValue, zExpressionValue, null); BinaryExpression ternaryAssign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(xVariableReference, null), ternaryConditionExpression, this.typeSystem, null); result = new ExpressionStatement(ternaryAssign) { Parent = theIfStatement.Parent }; FixContext(xVariableReference.Resolve(), 1, 0, result as ExpressionStatement); return true; }
protected void FixContext(VariableDefinition variable, int removedDefinitions, int removedUsages, ExpressionStatement newDefinition) { DefineUseCount defineUseCount; if (patternsContext.VariableToDefineUseCountContext.TryGetValue(variable, out defineUseCount)) { defineUseCount.DefineCount -= removedDefinitions; defineUseCount.UseCount -= removedUsages; if (defineUseCount.DefineCount == 1 && newDefinition != null) { patternsContext.VariableToSingleAssignmentMap[variable] = newDefinition; } } }
public override void VisitExpressionStatement(ExpressionStatement node) { if (node.IsAssignmentStatement() && node.Parent.CodeNodeType == CodeNodeType.BlockStatement) { BinaryExpression assignment = node.Expression as BinaryExpression; if (assignment.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression) { Visit(assignment.Right); AddDefinition((assignment.Left as VariableReferenceExpression).Variable.Resolve(), node); return; } } base.VisitExpressionStatement(node); }
public override void VisitExpressionStatement(ExpressionStatement node) { if (node.Expression is BinaryExpression) { BinaryExpression binEx = node.Expression as BinaryExpression; if (binEx.Operator == BinaryOperator.Assign) { if (binEx.Left is VariableReferenceExpression && binEx.Right is VariableReferenceExpression) { VariableReference leftVariable = (binEx.Left as VariableReferenceExpression).Variable; VariableReference rightVariable = (binEx.Right as VariableReferenceExpression).Variable; if (leftVariable == rightVariable) { statementsToRemove.Add(node); } } } } }
public bool IsOptimisableAssignment(ExpressionStatement statement) { BinaryExpression expr = statement.Expression as BinaryExpression; if (expr == null) { return false; } if (!expr.IsAssignmentExpression) { return false; } if (expr.Right.CodeNodeType == CodeNodeType.BinaryExpression && ((expr.Right as BinaryExpression).IsAssignmentExpression || (expr.Right as BinaryExpression).IsSelfAssign)) { return false; } if (expr.Left is VariableReferenceExpression || expr.Left is VariableDeclarationExpression) { return !new SideEffectsFinder().HasSideEffectsRecursive(expr.Right); } return false; }
public override ICodeNode VisitExpressionStatement(ExpressionStatement node) { if (node.Expression.CodeNodeType == CodeNodeType.BinaryExpression) { BinaryExpression binary = node.Expression as BinaryExpression; if (binary.IsAssignmentExpression ) { if (binary.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression) { RecordVariableAssignment(node); return node; } else if (binary.Left.CodeNodeType == CodeNodeType.ArrayIndexerExpression) { if (TryUpdateInitializer(node)) { return node; } } } } return base.VisitExpressionStatement(node); }
public override void VisitExpressionStatement(ExpressionStatement node) { ProcessExpression(node.Expression); }
//x = y ?? z; // //== // //x = y; //if(x == null) //{ // dummyVar = x; // x = z; //} // //x - stack variable //y, z - expressions //dummyVar - dummy variable(this assignment might be missing) private bool TryMatchInternal(StatementCollection statements, int startIndex, out Statement result) { result = null; if (statements.Count < startIndex + 2) { return false; } VariableReference xVariableReference; Expression yExpressionValue; Expression zExpressionValue; if (statements[startIndex].CodeNodeType != CodeNodeType.ExpressionStatement || statements[startIndex + 1].CodeNodeType != CodeNodeType.IfStatement) { return false; } if (!string.IsNullOrEmpty(statements[startIndex + 1].Label)) { return false; } BinaryExpression yToXAssingExpression = (statements[startIndex] as ExpressionStatement).Expression as BinaryExpression; if (!IsAssignToVariableExpression(yToXAssingExpression, out xVariableReference)) { return false; } yExpressionValue = yToXAssingExpression.Right; IfStatement theIfStatement = statements[startIndex + 1] as IfStatement; int zToXAssignIndex = ContainsDummyAssignment(theIfStatement.Then, xVariableReference) ? 1 : 0; if (theIfStatement.Else != null || theIfStatement.Then.Statements.Count != 1 + zToXAssignIndex || theIfStatement.Then.Statements[zToXAssignIndex].CodeNodeType != CodeNodeType.ExpressionStatement || !string.IsNullOrEmpty(theIfStatement.Then.Statements[zToXAssignIndex].Label)) { return false; } BinaryExpression theCondition = theIfStatement.Condition as BinaryExpression; if (theCondition == null || theCondition.Operator != BinaryOperator.ValueEquality || theCondition.Left.CodeNodeType != CodeNodeType.VariableReferenceExpression || (theCondition.Left as VariableReferenceExpression).Variable != xVariableReference || theCondition.Right.CodeNodeType != CodeNodeType.LiteralExpression || (theCondition.Right as LiteralExpression).Value != null) { return false; } BinaryExpression zToXAssignExpression = (theIfStatement.Then.Statements[zToXAssignIndex] as ExpressionStatement).Expression as BinaryExpression; VariableReference zVariable; if (zToXAssignExpression == null || !IsAssignToVariableExpression(zToXAssignExpression, out zVariable) || zVariable != xVariableReference) { return false; } zExpressionValue = zToXAssignExpression.Right; if (!yExpressionValue.HasType || !zExpressionValue.HasType || yExpressionValue.ExpressionType.FullName != zExpressionValue.ExpressionType.FullName) { return false; } BinaryExpression nullCoalescingEpxression = new BinaryExpression(BinaryOperator.NullCoalesce, yExpressionValue, zExpressionValue, typeSystem, null); BinaryExpression nullCoalescingAssign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(xVariableReference, null), nullCoalescingEpxression, typeSystem, null); result = new ExpressionStatement(nullCoalescingAssign) { Parent = statements[startIndex].Parent }; FixContext(xVariableReference.Resolve(), 1, zToXAssignIndex + 1, result as ExpressionStatement); return true; }
private bool TryRemoveExpressionStatment(ExpressionStatement statement) { BlockStatement blockParent = statement.Parent as BlockStatement; if (blockParent == null) { return false; } blockParent.Statements.Remove(statement); return true; }
private void RecordVariableAssignment(ExpressionStatement node) { BinaryExpression assignment = node.Expression as BinaryExpression; VariableReference variable = (assignment.Left as VariableReferenceExpression).Variable; assignment.Right = (Expression)Visit(assignment.Right); Expression rightClone = assignment.Right.CloneExpressionOnly(); this.variableToValueMap[variable] = rightClone; HashSet<ExpressionStatement> statements; if (!this.variableToAssigingStatementsMap.TryGetValue(variable, out statements)) { statements = new HashSet<ExpressionStatement>(); this.variableToAssigingStatementsMap[variable] = statements; } statements.Add(node); ArrayCreationExpression arrayCreation = rightClone as ArrayCreationExpression; if (arrayCreation == null || arrayCreation.Dimensions == null || arrayCreation.Dimensions.Count != 1 || arrayCreation.Initializer != null && arrayCreation.Initializer.Expressions != null && arrayCreation.Initializer.Expressions.Count > 0) { return; } var blockExpression = new BlockExpression(null); arrayCreation.Initializer = new InitializerExpression(blockExpression, InitializerType.ArrayInitializer); this.variableToLastUninitializedIndex[variable] = 0; }
private bool TryUpdateInitializer(ExpressionStatement node) { BinaryExpression assignment = node.Expression as BinaryExpression; ArrayIndexerExpression indexerExpression = assignment.Left as ArrayIndexerExpression; if (indexerExpression.Target == null || indexerExpression.Target.CodeNodeType != CodeNodeType.VariableReferenceExpression) { return false; } VariableReference variable = (indexerExpression.Target as VariableReferenceExpression).Variable; int lastUninitializedIndex; if (!this.variableToLastUninitializedIndex.TryGetValue(variable, out lastUninitializedIndex)) { return false; } if (indexerExpression.Indices == null || indexerExpression.Indices.Count != 1) { return false; } int index = GetIntegerValue(indexerExpression.Indices[0] as LiteralExpression); if (index != lastUninitializedIndex) { this.variableToLastUninitializedIndex.Remove(variable); this.variableToValueMap.Remove(variable); this.variableToAssigingStatementsMap.Remove(variable); if (this.usedVariables.Contains(variable)) { this.failure = true; } return false; } ArrayCreationExpression arrayCreation = this.variableToValueMap[variable] as ArrayCreationExpression; arrayCreation.Initializer.Expressions.Add((Expression)Visit(assignment.Right.CloneExpressionOnly())); this.variableToAssigingStatementsMap[variable].Add(node); this.variableToLastUninitializedIndex[variable] = index + 1; return true; }
public override void VisitExpressionStatement(ExpressionStatement node) { if (!assignments.Contains(node)) { base.VisitExpressionStatement(node); } }
/// <summary> /// Declare boolean variable for each label, and include <code>variable = false;</code> statements just after the label. /// Moves the label from the original statement to the variable assignment. /// </summary> private void AddLabelVariables() { List<Statement> oldLabels = new List<Statement>(methodContext.GotoLabels.Values); foreach (Statement oldLabel in oldLabels) { string label = oldLabel.Label; oldLabel.Label = string.Empty; VariableDefinition labelVariable = GetLabelVariable(label); ///Add cond = false expression right after the label. BlockStatement containingBlock = oldLabel.Parent as BlockStatement; ///All labeled statements must be inside BlockStatement. if (containingBlock == null) { throw new ArgumentOutOfRangeException("Label target is not within a block."); } int labelIndex = containingBlock.Statements.IndexOf(oldLabel); ///Generate the <code>variable=false;</code> statement; BinaryExpression assignment = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(labelVariable, null), GetLiteralExpression(false), typeSystem, null); assignment.Right.ExpressionType = methodContext.Method.Module.TypeSystem.Boolean; ExpressionStatement assignmentStatement = new ExpressionStatement(assignment); ///Add the label to the new assignment assignmentStatement.Label = label; methodContext.GotoLabels[label] = assignmentStatement; ///Push the assignment just before the old labeled statement variableToAssignment.Add(labelVariable, assignmentStatement); containingBlock.AddStatementAt(labelIndex, assignmentStatement); } }
protected bool TryGetAssignedVariable(ExpressionStatement node, out VariableReference variable) { variable = null; Expression variableExpression; BinaryExpression assign = node.Expression as BinaryExpression; if (assign != null && !assign.IsAssignmentExpression) { assign = null; } if (assign == null) { UnaryExpression unaryExpression = node.Expression as UnaryExpression; if (unaryExpression == null || unaryExpression.Operator != UnaryOperator.PostDecrement && unaryExpression.Operator != UnaryOperator.PostIncrement && unaryExpression.Operator != UnaryOperator.PreDecrement && unaryExpression.Operator != UnaryOperator.PreIncrement) { return false; } variableExpression = unaryExpression.Operand; } else { variableExpression = assign.Left; } if (variableExpression.CodeNodeType == CodeNodeType.VariableDeclarationExpression) { variable = ((VariableDeclarationExpression)variableExpression).Variable; } else if (variableExpression.CodeNodeType == CodeNodeType.VariableReferenceExpression) { variable = ((VariableReferenceExpression)variableExpression).Variable; } return variable != null; }
private void WriteSplitPropertySetter(PropertyDefinition property) { WriteKeyword(KeyWordWriter.Set); WriteBeginBlock(); WriteLine(); Indent(); MethodReferenceExpression jdSetterReference = new MethodReferenceExpression(null, property.SetMethod, null); MethodInvocationExpression jdMethodInvocation = new MethodInvocationExpression(jdSetterReference, null); jdMethodInvocation.Arguments = CopyMethodParametersAsArguments(property.SetMethod); ExpressionStatement toWrite = new ExpressionStatement(jdMethodInvocation); Write(toWrite); WriteLine(); Outdent(); WriteEndBlock("Set"); }
private void ClearState() { insideTry = false; foundEnumeratorAssignment = false; foundWhile = false; foreachCollection = null; foreachVariable = null; foreachVariableInstructions.Clear(); foreachCollectionInstructions.Clear(); foreachBody = new BlockStatement(); theEnumerator = null; theTry = null; @foreach = null; enumeratorAssignmentStatement = null; foreachVariableType = null; isEnumeratorUsedInsideForEach = false; foreachConditionInstructions = null; }
/// <summary> /// Eliminates the goto statement via introducing do-while. Should be used when the goto comes after the label. /// </summary> /// <param name="gotoStatement">The goto statement.</param> /// <param name="labeledStatement">The labeled statement.</param> private void EliminateViaDoWhile(IfStatement gotoStatement, Statement labeledStatement) { ICollection<BreakStatement> breaks = new List<BreakStatement>(); ICollection<ContinueStatement> continues = new List<ContinueStatement>(); BlockStatement containingBlock = GetOuterBlock(labeledStatement); int labelIndex = containingBlock.Statements.IndexOf(labeledStatement); int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); BlockStatement loopBody = CollectStatements(labelIndex, gotoIndex, containingBlock); /// Checks if the gotoStatement is inside a loop/switch statement. /// If so, then some breaks might be enclosed in the new do-while. Additional breaks need to be included in this case if (ShouldCheck(gotoStatement)) { ContinueAndBreakFinder finder = new ContinueAndBreakFinder(); finder.Visit(loopBody); breaks = finder.Breaks; continues = finder.Continues; } /// Add condition = true before each enclosed break statement. foreach (BreakStatement statement in breaks) { BlockStatement breakBlock = GetOuterBlock(statement); int breakIndex = breakBlock.Statements.IndexOf(statement); BinaryExpression assign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(breakVariable, null), GetLiteralExpression(true), typeSystem, null); usedBreakVariable = true; ExpressionStatement assignment = new ExpressionStatement(assign); breakBlock.AddStatementAt(breakIndex, assignment); } /// Add condition = true before each enclosed continue statement /// and replace the continue statement with break statement foreach (ContinueStatement statement in continues) { BlockStatement continueBlock = GetOuterBlock(statement); int continueIndex = continueBlock.Statements.IndexOf(statement); BinaryExpression assign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(continueVariable, null), GetLiteralExpression(true), typeSystem, null); usedContinueVariable = true; ExpressionStatement assignment = new ExpressionStatement(assign); continueBlock.Statements.RemoveAt(continueIndex); continueBlock.AddStatementAt(continueIndex, new BreakStatement(null)); continueBlock.AddStatementAt(continueIndex, assignment); } /// Replace the goto with do-while loop. DoWhileStatement doWhileLoop = new DoWhileStatement(gotoStatement.Condition, loopBody); gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); containingBlock.AddStatementAt(gotoIndex, doWhileLoop); containingBlock.Statements.Remove(gotoStatement); if (breaks.Count > 0) { /// Add condition for the outer break, accounting for the enclosed breaks. AddBreakContinueConditional(gotoIndex + 1, containingBlock, new BreakStatement(null), breakVariable);//gotoindex + 1 should be the place after the newly inserted do-while loop } if (continues.Count > 0) { /// Add condition for the outer break, accounting for the enclosed continues. AddBreakContinueConditional(gotoIndex + 1, containingBlock, new ContinueStatement(null), continueVariable); } }
private void TransferLabel(ExpressionStatement expressionStatement) { if (expressionStatement.Label == string.Empty) { return; } string theLabel = expressionStatement.Label; Statement currentStatement = expressionStatement; while (currentStatement.Parent != null) { BlockStatement parent = currentStatement.Parent as BlockStatement; int statementIndex = parent.Statements.IndexOf(currentStatement); if (statementIndex != parent.Statements.Count - 1) { Statement nextStatement = parent.Statements[statementIndex + 1]; MoveLabel(nextStatement, theLabel); return; } else if (IsLoopBody(parent)) { Statement firstStatement = parent.Statements[0]; MoveLabel(firstStatement, theLabel); return; } do { currentStatement = currentStatement.Parent; } while (currentStatement.Parent != null && currentStatement.Parent.CodeNodeType != CodeNodeType.BlockStatement); } EmptyStatement emptyStatement = new EmptyStatement(); this.theBody.Statements.Add(emptyStatement); MoveLabel(emptyStatement, theLabel); }
public void CleanUpUnusedDeclarations() { foreach (KeyValuePair<VariableReference, ExpressionStatement> referenceToStatementPair in referenceToDeclarationStatementMap) { VariableReference variableReference = referenceToStatementPair.Key; context.MethodContext.RemoveVariable(variableReference); ExpressionStatement declarationStatement = referenceToStatementPair.Value; BlockStatement parentBlock = declarationStatement.Parent as BlockStatement; if (IsOptimisableAssignment(declarationStatement)) { TransferLabel(declarationStatement); parentBlock.Statements.Remove(declarationStatement); } else { /// check if the right side can exist on its own Expression rightSide = (declarationStatement.Expression as BinaryExpression).Right; if (CanExistInStatement(rightSide)) { if (rightSide.CodeNodeType == CodeNodeType.ParenthesesExpression) { rightSide = (rightSide as ParenthesesExpression).Expression; } ExpressionStatement newStatement = new ExpressionStatement(rightSide); int index = parentBlock.Statements.IndexOf(declarationStatement); parentBlock.AddStatementAt(index + 1, newStatement); TransferLabel(declarationStatement); parentBlock.Statements.RemoveAt(index); } } } HashSet<VariableDefinition> unusedVariables = new HashSet<VariableDefinition>(); foreach (VariableDefinition variable in context.MethodContext.Variables) { if (!bannedVariables.Contains(variable)) { unusedVariables.Add(variable); } } foreach (VariableDefinition variable in unusedVariables) { context.MethodContext.RemoveVariable(variable); } }
private bool IsFieldAssignment(ExpressionStatement fieldAssignmentStatement, out Expression assignedValue, out string fieldFullName) { fieldFullName = null; assignedValue = null; BinaryExpression theFieldAssignment = fieldAssignmentStatement.Expression as BinaryExpression; if (theFieldAssignment == null || !theFieldAssignment.IsAssignmentExpression || theFieldAssignment.Left.CodeNodeType != CodeNodeType.FieldReferenceExpression) { return false; } FieldReference theField = (theFieldAssignment.Left as FieldReferenceExpression).Field; if (theField == null) { return false; } assignedValue = theFieldAssignment.Right; fieldFullName = theField.FullName; return true; }
private bool CheckTheInitializer(ExpressionStatement statement, out VariableReference forVariable) { forVariable = null; return statement != null && statement.IsAssignmentStatement() && TryGetAssignedVariable(statement, out forVariable); }
private bool IsAutoPropertyAssignment(ExpressionStatement propertyAssignmentStatement, out Expression assignedValue, out string propertyFullName) { propertyFullName = null; assignedValue = null; BinaryExpression thePropertyAssignment = propertyAssignmentStatement.Expression as BinaryExpression; if (thePropertyAssignment == null || !thePropertyAssignment.IsAssignmentExpression || thePropertyAssignment.Left.CodeNodeType != CodeNodeType.AutoPropertyConstructorInitializerExpression) { return false; } PropertyDefinition theProperty = (thePropertyAssignment.Left as AutoPropertyConstructorInitializerExpression).Property; if (theProperty == null) { return false; } assignedValue = thePropertyAssignment.Right; propertyFullName = theProperty.FullName; return true; }
/// <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 VisitExpressionStatement(ExpressionStatement node) { Visit(node.Expression); if ((ShouldOmitSemicolon.Count == 0) || (!ShouldOmitSemicolon.Peek())) { WriteEndOfStatement(); } }
private bool CheckVariableInitialization(ExpressionStatement node) { if (!node.IsAssignmentStatement()) { return false; } BinaryExpression theAssignExpression = node.Expression as BinaryExpression; if (theAssignExpression.Left.CodeNodeType != CodeNodeType.VariableReferenceExpression) { return false; } Expression value = theAssignExpression.Right; if (value.CodeNodeType == CodeNodeType.CastExpression) { value = (value as CastExpression).Expression; } if ((value.CodeNodeType != CodeNodeType.LiteralExpression || (value as LiteralExpression).Value != null) && (value.CodeNodeType != CodeNodeType.FieldReferenceExpression)) { return false; } if (value.CodeNodeType == CodeNodeType.FieldReferenceExpression) { FieldReferenceExpression fieldReferenceExpression = value as FieldReferenceExpression; TypeDefinition fieldType = fieldReferenceExpression.ExpressionType.Resolve(); if (fieldType == null || fieldType.BaseType == null || fieldType.BaseType.FullName != "System.MulticastDelegate") { return false; } // Slow checks FieldDefinition fieldDef = fieldReferenceExpression.Field.Resolve(); if ((fieldDef.DeclaringType != this.context.MethodContext.Method.DeclaringType && !fieldDef.DeclaringType.IsNestedIn(this.context.MethodContext.Method.DeclaringType)) || !fieldDef.DeclaringType.IsCompilerGenerated()) { return false; } } initializationsToRemove[(theAssignExpression.Left as VariableReferenceExpression).Variable] = node; return true; }
public override void VisitExpressionStatement(ExpressionStatement node) { if (!foundWhile) { if (IsEnumeratorAssignment(node.Expression)) { foundEnumeratorAssignment = true; enumeratorAssignmentStatement = node; return; } } else { if (node.Expression is BinaryExpression) { if (!IsForeachVariableAssignment(node.Expression as BinaryExpression)) { if (shouldAdd) { foreachBody.AddStatement(node); } } } else if (node.Expression is MethodInvocationExpression || node.Expression is PropertyReferenceExpression) { if (IsGetCurrent(node.Expression)) { //covers the case where the foreach variable is not used this.foreachVariableType = node.Expression.ExpressionType; } else { if (shouldAdd) { foreachBody.AddStatement(node); } } } else if (node.Expression is CastExpression) { CastExpression theCast = node.Expression as CastExpression; if (IsGetCurrent(theCast.Expression)) { this.foreachVariableType = theCast.ExpressionType; } else { if (shouldAdd) { foreachBody.AddStatement(node); } } } else if (node.Expression is BoxExpression) { BoxExpression theBox = node.Expression as BoxExpression; if (IsGetCurrent(theBox.BoxedExpression)) { this.foreachVariableType = theBox.BoxedAs; } else { if (shouldAdd) { foreachBody.AddStatement(node); } } } else { if (shouldAdd) { foreachBody.AddStatement(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; }