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);
			}
		}
예제 #2
0
        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;
		}
예제 #13
0
 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;
		}
예제 #16
0
 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;
		}
예제 #26
0
 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;
        }