private void TryRemoveConditionVariable(BlockStatement node, Statement statement, int index) { if (!(statement is ExpressionStatement)) return; var expressionStatement = (ExpressionStatement) statement; if (!(expressionStatement.Expression.CodeNodeType == CodeNodeType.BinaryExpression && (expressionStatement.Expression as BinaryExpression).IsAssignmentExpression)) return; var assingExpression = (BinaryExpression) expressionStatement.Expression; if (!(assingExpression.Left is VariableReferenceExpression)) return; if (assingExpression.Right is MethodInvocationExpression) { var variable = assingExpression.Left as VariableReferenceExpression; if (variable.Variable.VariableType.Name != TypeCode.Boolean.ToString()) return; } var variableReferenceExpression = (VariableReferenceExpression) assingExpression.Left; if (ContainsKey(variableReferenceExpression.Variable)) { methodContext.RemoveVariable(variableReferenceExpression.Variable); node.Statements.RemoveAt(index); } }
public CatchClause(BlockStatement body, TypeReference type, VariableDeclarationExpression variable, Statement filter = null) { this.Body = body; this.Type = type; this.Variable = variable; this.Filter = filter; }
public virtual bool TryMatch(StatementCollection statements, out int startIndex, out Statement result, out int replacedStatementsCount) { startIndex = -1; result = null; replacedStatementsCount = -1; if (statements == null || statements.Count - startIndex < 2) { return false; } for (int i = statements.Count - 1; i >= 0; i--) { if (TryMatchInternal(statements, i, out result, out replacedStatementsCount)) { Expression expression = ((result as ExpressionStatement).Expression as BinaryExpression).Left; if (expression.CodeNodeType == CodeNodeType.VariableReferenceExpression) { FixContext((expression as VariableReferenceExpression).Variable.Resolve(), 0, replacedStatementsCount - 1, null); } startIndex = i; return true; } } return false; }
private Statement FixSwitchingStatement(Statement statement) { if (statement is SwitchStatement) { SwitchStatement theSwitch = statement as SwitchStatement; if (theSwitch.Condition.Equals(theIntVariable)) { theSwitch.Condition = theStringVariable.CloneExpressionOnly(); } foreach (SwitchCase @case in theSwitch.Cases) { if (@case is ConditionCase) { ConditionCase condCase = @case as ConditionCase; int caseValue = (int)(condCase.Condition as LiteralExpression).Value; condCase.Condition = new LiteralExpression(valueDictionary[caseValue], theTypeSystem, null); } } } else if (statement is IfElseIfStatement) { IfElseIfStatement irregularSwitch = statement as IfElseIfStatement; foreach (KeyValuePair<Expression, BlockStatement> condPair in irregularSwitch.ConditionBlocks) { FixConditionExpression(condPair.Key as BinaryExpression); } } return statement; }
public DecompiledMember(string memberName, Telerik.JustDecompiler.Ast.Statements.Statement statement, MethodSpecificContext context) { base(); this.set_MemberFullName(memberName); this.set_Statement(statement); this.set_Context(context); return; }
public bool TryMatch(StatementCollection statements,out int startIndex, out Statement result, out int replacedStatementsCount) { result = null; startIndex = 0; bool matched = TryMatchArrayAssignmentInternal(statements); if (matched) { replacedStatementsCount = 2; return true; } replacedStatementsCount = 1; return TryMatchDirectAssignmentInternal(statements); }
public bool TryMatch(StatementCollection statements, out int startIndex, out Statement result, out int replacedStatementsCount) { replacedStatementsCount = 0; startIndex = -1; result = null; bool inlinedSuccessfully = false; if(statements.Count == 0) { return false; } HashSet<VariableDefinition> markedForRemoval = new HashSet<VariableDefinition>(); List<int> positionsToInline = GetStatementsToInline(statements); for (int i = positionsToInline.Count - 1; i >= 0; i--) { int index = positionsToInline[i]; ExpressionStatement defineExpression = statements[index] as ExpressionStatement; VariableDefinition variable = ((defineExpression.Expression as BinaryExpression).Left as VariableReferenceExpression).Variable.Resolve(); if (index == statements.Count - 1 || !string.IsNullOrEmpty(defineExpression.Label)) { markedForRemoval.Add(variable); continue; } List<Instruction> instructions = new List<Instruction>(defineExpression.Expression.MappedInstructions); instructions.AddRange((defineExpression.Expression as BinaryExpression).Left.UnderlyingSameMethodInstructions); Expression value = (defineExpression.Expression as BinaryExpression).Right.CloneAndAttachInstructions(instructions); ICodeNode resultNode; if (inliner.TryInlineVariable(variable, value, statements[index + 1], ShouldInlineAggressively(variable), out resultNode)) { statements.RemoveAt(index); inlinedSuccessfully = true; markedForRemoval.Add(variable); methodContext.RemoveVariable(variable); } } foreach (VariableDefinition variable in markedForRemoval) { patternsContext.VariableToSingleAssignmentMap.Remove(variable); patternsContext.VariableToDefineUseCountContext.Remove(variable); } return inlinedSuccessfully; }
//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; }
public bool TryMatch(StatementCollection statements, out int startIndex, out Statement result, out int replacedStatementsCount) { result = null; replacedStatementsCount = 2; for (startIndex = 0; startIndex + 1 < statements.Count; startIndex++) { bool currentTransform = TryMatchInternal(statements, startIndex, out result); if (currentTransform) { return true; } } return false; }
private bool EliminateGotoPair(GotoStatement gotoStatement, Statement labeledStatement) { if (TryRemoveChainedGoto(labeledStatement, gotoStatement)) { return true; } if (TryRemoveGoto(labeledStatement, gotoStatement)) { return true; } if (TryCopyTargetedBlock(labeledStatement, gotoStatement)) { return true; } //TODO: Add more steps return false; }
private bool IsCtorInvocation(Statement statement, out bool isBaseCtor) { isBaseCtor = false; if (statement.CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } MethodInvocationExpression theMethodInvokeExpression = (statement as ExpressionStatement).Expression as MethodInvocationExpression; if (theMethodInvokeExpression == null || theMethodInvokeExpression.CodeNodeType != CodeNodeType.BaseCtorExpression && theMethodInvokeExpression.CodeNodeType != CodeNodeType.ThisCtorExpression) { return false; } isBaseCtor = theMethodInvokeExpression.CodeNodeType == CodeNodeType.BaseCtorExpression; return true; }
private bool IsAsyncFirstAssignmentStatement(Statement statement, out TypeDefinition asyncStateMachineType) { asyncStateMachineType = null; if (statement is ExpressionStatement) { ExpressionStatement expressionStatement = statement as ExpressionStatement; if (expressionStatement.Expression is BinaryExpression) { BinaryExpression binary = expressionStatement.Expression as BinaryExpression; if (binary.Right is ThisReferenceExpression && binary.Left is FieldReferenceExpression) { FieldReferenceExpression fieldExpression = binary.Left as FieldReferenceExpression; TypeReference typeReference = fieldExpression.Field.DeclaringType; if (typeReference == null) { return false; } TypeDefinition typeDef = typeReference.Resolve(); if (typeDef == null || typeDef.DeclaringType != this.methodContext.Method.DeclaringType || !typeDef.IsAsyncStateMachine()) { return false; } asyncStateMachineType = typeDef; return true; } } } return false; }
protected void CopyParentAndLabel(Statement target) { target.Label = this.Label; target.Parent = this.Parent; }
// Person person = new Person { Name = "John", Age = 20 }; // // == // // Person person = new Person(); // person.Name = "John"; // person.Age = 20; protected override bool TryMatchInternal(StatementCollection statements, int startIndex, out Statement result, out int replacedStatementsCount) { result = null; replacedStatementsCount = 0; ObjectCreationExpression objectCreation; Expression assignee; if (!TryGetObjectCreation(statements, startIndex, out objectCreation, out assignee)) { return false; } ExpressionCollection inlinedExpressions = new ExpressionCollection(); HashSet<string> visitedPropertyNames = new HashSet<string>(); if (objectCreation.Initializer != null) { if (objectCreation.Initializer.InitializerType != InitializerType.ObjectInitializer) { return false; } foreach (var item in objectCreation.Initializer.Expressions) { string name = GetName((item as BinaryExpression).Left); visitedPropertyNames.Add(name); } } for (int i = startIndex + 1; i < statements.Count; i++) { Expression expression; if (!TryGetNextExpression(statements[i], out expression)) { break; } BinaryExpression assignment = expression as BinaryExpression; if (!IsObjectPropertyOrFieldAssignment(assignment, assignee)) { break; } Expression initializer = null; if (assignment.Left.CodeNodeType == CodeNodeType.PropertyReferenceExpression) { PropertyDefinition property = (assignment.Left as PropertyReferenceExpression).Property; if (!Visit(property.Name, visitedPropertyNames)) { break; } initializer = new PropertyInitializerExpression(property, property.PropertyType, assignment.Right.UnderlyingSameMethodInstructions); } else if (assignment.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression) { FieldDefinition field = (assignment.Left as FieldReferenceExpression).Field.Resolve(); if (!Visit(field.Name, visitedPropertyNames)) { break; } initializer = new FieldInitializerExpression(field, field.FieldType, assignment.Right.UnderlyingSameMethodInstructions); } var inlinedAssignment = new BinaryExpression(BinaryOperator.Assign, initializer, assignment.Right.Clone(), this.typeSystem, null); inlinedExpressions.Add(inlinedAssignment); } if (inlinedExpressions.Count == 0) { return false; } if (objectCreation.Initializer == null) { var initializer = new InitializerExpression(inlinedExpressions, InitializerType.ObjectInitializer); initializer.IsMultiLine = true; objectCreation.Initializer = initializer; } else { foreach (var item in inlinedExpressions) { objectCreation.Initializer.Expressions.Add(item); } } result = statements[startIndex]; replacedStatementsCount = inlinedExpressions.Count + 1; return true; }
public DecompiledMember(string memberName, Statement statement, MethodSpecificContext context) { this.MemberFullName = memberName; this.Statement = statement; this.Context = context; }
public void AddStatementAt(int index, Statement statement) { this.statements.Insert(index, statement); statement.Parent = this; }
private void MoveLabel(Statement destination, string theLabel) { if (destination.Label == string.Empty) { destination.Label = theLabel; this.context.MethodContext.GotoLabels[theLabel] = destination; } else { string newLabel = destination.Label; foreach (GotoStatement gotoStatement in this.context.MethodContext.GotoStatements) { if (gotoStatement.TargetLabel == theLabel) { gotoStatement.TargetLabel = newLabel; } } this.context.MethodContext.GotoLabels.Remove(theLabel); } }
//Removes statements from index to index + length - 1 //Inserts newStatement at index private void RemoveRangeAndInsert(StatementCollection statements, int startIndex, int length, Statement newStatement) { statements[startIndex] = newStatement; RemoveRange(statements, startIndex + 1, length - 1); }
protected virtual void Write(Statement statement) { }
private ForStatement CreateForStatement(Statement initializer, WhileStatement theWhile) { int forStatementsCount = theWhile.Body.Statements.Count - 1; string incrementLabel = theWhile.Body.Statements[forStatementsCount].Label; ForStatement result = new ForStatement( (initializer as ExpressionStatement).Expression, theWhile.Condition, (theWhile.Body.Statements[forStatementsCount] as ExpressionStatement).Expression, new BlockStatement()); for (int i = 0; i < forStatementsCount; i++) { result.Body.AddStatement(theWhile.Body.Statements[i]); } if (!string.IsNullOrEmpty(incrementLabel)) { EmptyStatement emptyStatement = new EmptyStatement() { Label = incrementLabel }; result.Body.AddStatement(emptyStatement); } return result; }
protected abstract bool TryMatchInternal(StatementCollection statements, int startIndex, out Statement result, out int replacedStatementsCount);
public StatementExpression(Expression expression, Statement parentWhileStatement) { this.expression = expression; this.parentWhileStatement = parentWhileStatement; }
private void TryRemoveReturnStatement(BlockStatement node, Statement statement, int index) { if (statement.CodeNodeType == CodeNodeType.ExpressionStatement && (statement as ExpressionStatement).Expression.CodeNodeType ==CodeNodeType.ReturnExpression) { var returnExpression = (ReturnExpression)(statement as ExpressionStatement).Expression; if (!(returnExpression.Value is VariableReferenceExpression)) return; var variableReference = returnExpression.Value as VariableReferenceExpression; if (variableReference == null) { //Other expressions can be returned as well //for instance MethodInvocation and literal expressions //as this is legacy code, the chesk is here to ensure that no exception is thrown due to null reference //Investigate the logic and provide further fixes. return; } VariableStateAndExpression variableStateAndExpression; if (TryGetValue(variableReference.Variable, out variableStateAndExpression)) { if (variableStateAndExpression.VariableState == VariableState.Return) { methodContext.RemoveVariable(variableReference.Variable); node.Statements.RemoveAt(index); } } } }
public GeneratedMethod(MethodDefinition method, Statement body, MethodSpecificContext context) { this.Method = method; this.Body = body; this.Context = context; }
protected bool TryGetNextExpression(Statement statement, out Expression expression) { expression = null; if (statement.CodeNodeType != CodeNodeType.ExpressionStatement || !string.IsNullOrEmpty(statement.Label)) { return false; } expression = (statement as ExpressionStatement).Expression; return true; }
public void AddStatement(Statement statement) { AddStatementAt(statements.Count, statement); }
private bool IsChildOfCurrentStatement(Statement statement) { foreach (var childStatement in statements) { if (childStatement == statement) { return true; } } return false; }
protected override void Write(Statement statement) { Visit(statement); }
public StatementDeclaration(Statement statement) { this.Statement = statement; }
private bool IsVariableDeclaration(Statement statements) { if (statements.CodeNodeType != CodeNodeType.ExpressionStatement) { return false; } if (((ExpressionStatement)statements).Expression.CodeNodeType != CodeNodeType.VariableDeclarationExpression) { return false; } return true; }
public bool TryMatch(StatementCollection statements,out int startIndex, out Statement result, out int replacedStatementsCount) { result = null; replacedStatementsCount = 1; for (startIndex = 0; startIndex < statements.Count; startIndex++) { if (statements[startIndex].CodeNodeType != CodeNodeType.IfStatement) { continue; } if (TryMatchInternal(statements[startIndex] as IfStatement, out result)) { return true; } } return false; }
private int GetParentWhileStatementIndex(List<StatementExpression> statementExpressions, Statement parentWhileStatement) { for (int i = 0; i < statementExpressions.Count; i++) { if (statementExpressions[i].Statement == parentWhileStatement) { return i; } } return 0; }
private bool IsDelegateOperationStatement(Statement statement, string operationName, out Expression newValueHolder, out Expression oldValueHolder) { newValueHolder = null; oldValueHolder = null; if (!statement.IsAssignmentStatement()) { return false; } BinaryExpression assignExpression = (statement as ExpressionStatement).Expression as BinaryExpression; if (assignExpression.Right.CodeNodeType != CodeNodeType.CastExpression || (assignExpression.Right as CastExpression).Expression.CodeNodeType != CodeNodeType.MethodInvocationExpression) { return false; } MethodInvocationExpression methodInvokeExpr = (assignExpression.Right as CastExpression).Expression as MethodInvocationExpression; if (methodInvokeExpr.Arguments.Count != 2 || methodInvokeExpr.MethodExpression.Method.HasThis || methodInvokeExpr.MethodExpression.Method.DeclaringType.FullName != "System.Delegate" || methodInvokeExpr.MethodExpression.Method.Name != operationName) { return false; } if (methodInvokeExpr.Arguments[1].CodeNodeType != CodeNodeType.ArgumentReferenceExpression) { return false; } newValueHolder = assignExpression.Left; oldValueHolder = methodInvokeExpr.Arguments[0]; return true; }