public CatchClause(BlockStatement body, TypeReference type, VariableDeclarationExpression variable, Statement filter = null)
        {
            this.Body = body;
            this.Type = type;
            this.Variable = variable;
            this.Filter = filter;
		}
		public ArrayVariableDeclarationExpression(VariableDeclarationExpression 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 ArrayVariableDeclarationExpression(VariableDeclarationExpression 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 VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     if (node.Variable == variable)
     {
         found = true;
         return;
     }
     base.VisitVariableDeclarationExpression(node);
 }
 public ArrayVariableDeclarationExpression(VariableDeclarationExpression variable, TypeReference arrayType, ExpressionCollection dimensions, bool hasInitializer, IEnumerable <Instruction> instructions)
 {
     base(instructions);
     this.set_Variable(variable);
     this.set_ArrayType(arrayType);
     this.set_Dimensions(dimensions);
     this.set_HasInitializer(hasInitializer);
     return;
 }
        public override bool Equals(Expression other)
        {
            if (!(other is VariableDeclarationExpression))
            {
                return(false);
            }
            VariableDeclarationExpression otherVar = other as VariableDeclarationExpression;

            return(this.Variable.Resolve() == otherVar.Variable.Resolve());
        }
        public ForEachStatement(VariableDeclarationExpression variable, Expression expression, BlockStatement body, IEnumerable<Instruction> conditionInstructions,
            IEnumerable<Instruction> finallyInstructions)
        {
			this.Variable = variable;
			this.Collection = expression;
			this.Body = body;

            this.mappedConditionInstructions = new List<Instruction>();
            if (conditionInstructions != null)
            {
                this.mappedConditionInstructions.AddRange(conditionInstructions);
                this.mappedConditionInstructions.Sort((x, y) => x.Offset.CompareTo(y.Offset));
            }
            
            this.mappedFinallyInstructions = new List<Instruction>();
            if (finallyInstructions != null)
            {
                this.mappedFinallyInstructions.AddRange(finallyInstructions);
                this.mappedFinallyInstructions.Sort((x, y) => x.Offset.CompareTo(y.Offset));
            }
        }
        private void GenerateForeachStatement()
        {
            if (foreachVariable == null)
            {
                foreachVariable = new VariableDefinition(foreachVariableType);
                foreachVariableInstructions.Clear();
                this.methodContext.VariablesToRename.Add(foreachVariable);
            }
            VariableDeclarationExpression vd = new VariableDeclarationExpression(foreachVariable, foreachVariableInstructions);

            Expression foreachCollectionExpression = foreachCollection.CloneAndAttachInstructions(foreachCollectionInstructions);
            if (foreachCollectionExpression is BaseReferenceExpression)
            {
                foreachCollectionExpression = new ThisReferenceExpression(this.methodContext.Method.DeclaringType, foreachCollectionExpression.UnderlyingSameMethodInstructions);
            }

            @foreach = new ForEachStatement(vd, foreachCollectionExpression, foreachBody, foreachConditionInstructions, theTry.Finally.UnderlyingSameMethodInstructions);
            GetCurrentFixer gcf = new GetCurrentFixer(theEnumerator, foreachVariable);
            gcf.Visit(@foreach);

            IsEnumeratorUsedVisitor enumeratorUsedVisitor = new IsEnumeratorUsedVisitor(theEnumerator);
            enumeratorUsedVisitor.Visit(@foreach);
            isEnumeratorUsedInsideForEach = enumeratorUsedVisitor.IsEnumeratorUsed;
        }
		public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
		{
			TypesDependingOn.UnionWith(Utilities.GetTypeReferenceTypesDepedningOn(node.Variable.VariableType));
			base.VisitVariableDeclarationExpression(node);
		}
        /*
         * The following pattern matches BlockStatements with similar content
         * {
         *      stackVariable6 = exception_0 as Exception;
         *      if (stackVariable6 != null)
	     *      {
         *          ProjectData.SetProjectError(stackVariable6);
         *          ex = stackVariable6;
		 *          stackVariable15 = Program.Bool() && b is int;
	     *      }
	     *      else
	     *      {
		 *          stackVariable15 = false;
	     *      }
	     *      stackVariable15;
         * }
         * - stackVariable6 = exception_0 as Exception; - the VariableDeclarationExpression is build using this variable reference
         * - Program.Bool() && b is int - The filter expression
         * - ex = stackVariable6; - Not required line, if present the variable reference is used to build the VariableDeclarationExpression
         * - ProjectData.SetProjectError(stackVariable6); - Not required line. It is generated by the VB compiler. It could be after ex = stackVariable6;
        */
        public static bool TryMatch(BlockStatement filter, out VariableDeclarationExpression variableDeclaration, out Expression filterExpression)
        {
            variableDeclaration = null;
            filterExpression = null;

            if (!TryMatchVariableDeclaration(filter, out variableDeclaration))
            {
                return false;
            }

            // Save cast of the exception
            // If-else statement for the filter expression
            // Variable reference of the result of the filter block
            if (filter.Statements.Count != 3)
            {
                return false;
            }

            IfStatement ifStatement = filter.Statements[1] as IfStatement;
            if (ifStatement == null)
            {
                return false;
            }

            BlockStatement exceptionAssignmentBlock = null;
            BlockStatement negativeFilterResultAssignmentBlock = null;
            if ((ifStatement.Condition as BinaryExpression).Operator == BinaryOperator.ValueInequality)
            {
                exceptionAssignmentBlock = ifStatement.Then;
                negativeFilterResultAssignmentBlock = ifStatement.Else;
            }
            else
            {
                exceptionAssignmentBlock = ifStatement.Else;
                negativeFilterResultAssignmentBlock = ifStatement.Then;
            }

            ExpressionStatement exceptionAssignmentStatement = null;
            ExpressionStatement methodInvocationStatement = null;
            if ((exceptionAssignmentBlock.Statements.Count != 1 && exceptionAssignmentBlock.Statements.Count != 2 && exceptionAssignmentBlock.Statements.Count != 3) ||
                negativeFilterResultAssignmentBlock.Statements.Count != 1)
            {
                return false;
            }

            if (exceptionAssignmentBlock.Statements.Count == 2)
            {
                ExpressionStatement firstThenStatement = exceptionAssignmentBlock.Statements[0] as ExpressionStatement;
                if (firstThenStatement == null)
                {
                    return false;
                }

                if (firstThenStatement.Expression.CodeNodeType == CodeNodeType.BinaryExpression)
                {
                    exceptionAssignmentStatement = firstThenStatement;
                }
                else if (firstThenStatement.Expression.CodeNodeType == CodeNodeType.MethodInvocationExpression)
                {
                    methodInvocationStatement = firstThenStatement;
                }
                else
                {
                    return false;
                }
            }
            else if (exceptionAssignmentBlock.Statements.Count == 3)
            {
                ExpressionStatement firstThenStatement = exceptionAssignmentBlock.Statements[0] as ExpressionStatement;
                ExpressionStatement secondThenStatement = exceptionAssignmentBlock.Statements[1] as ExpressionStatement;
                if (firstThenStatement == null || secondThenStatement == null)
                {
                    return false;
                }

                if (firstThenStatement.Expression.CodeNodeType == CodeNodeType.BinaryExpression &&
                    secondThenStatement.Expression.CodeNodeType == CodeNodeType.MethodInvocationExpression)
                {
                    exceptionAssignmentStatement = firstThenStatement;
                    methodInvocationStatement = secondThenStatement;
                }
                else if (firstThenStatement.Expression.CodeNodeType == CodeNodeType.MethodInvocationExpression &&
                    secondThenStatement.Expression.CodeNodeType == CodeNodeType.BinaryExpression)
                {
                    methodInvocationStatement = firstThenStatement;
                    exceptionAssignmentStatement = secondThenStatement;
                }
                else
                {
                    return false;
                }
            }

            if (exceptionAssignmentStatement != null)
            {
                BinaryExpression exceptionAssignment = exceptionAssignmentStatement.Expression as BinaryExpression;
                if (exceptionAssignment == null || !exceptionAssignment.IsAssignmentExpression ||
                    exceptionAssignment.ExpressionType.FullName != variableDeclaration.ExpressionType.FullName)
                {
                    return false;
                }

                VariableReferenceExpression left = exceptionAssignment.Left as VariableReferenceExpression;
                VariableReferenceExpression right = exceptionAssignment.Right as VariableReferenceExpression;
                if (left == null || right == null)
                {
                    return false;
                }
            }

            if (methodInvocationStatement != null)
            {
                MethodInvocationExpression methodInvocation = methodInvocationStatement.Expression as MethodInvocationExpression;
                if (methodInvocation == null ||
                    methodInvocation.MethodExpression.Method.FullName != "System.Void Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(System.Exception)")
                {
                    return false;
                }
            }
            
            ExpressionStatement lastExpressionStatement = filter.Statements[2] as ExpressionStatement;
            if (lastExpressionStatement == null)
            {
                return false;
            }

            VariableReferenceExpression lastExpression = lastExpressionStatement.Expression as VariableReferenceExpression;
            if (lastExpression == null)
            {
                return false;
            }

            if (!TryMatchFilterExpression(ifStatement, variableDeclaration.Variable.VariableType, lastExpression, out filterExpression))
            {
                return false;
            }

            return true;
        }
        private static bool TryMatchVariableDeclaration(BlockStatement filter, out VariableDeclarationExpression variableDeclaration)
        {
            variableDeclaration = null;

            ExpressionStatement firstExpressionStatement = filter.Statements[0] as ExpressionStatement;
            if (firstExpressionStatement == null)
            {
                return false;
            }

            BinaryExpression binaryExpression = firstExpressionStatement.Expression as BinaryExpression;
            if (binaryExpression == null || !binaryExpression.IsAssignmentExpression)
            {
                return false;
            }

            VariableReferenceExpression variableReference = binaryExpression.Left as VariableReferenceExpression;
            if (variableReference == null)
            {
                return false;
            }

            SafeCastExpression safeCast = binaryExpression.Right as SafeCastExpression;
            if (safeCast == null)
            {
                return false;
            }

            IfStatement ifStatement = filter.Statements[1] as IfStatement;
            if (ifStatement == null)
            {
                return false;
            }

            BinaryExpression condition = ifStatement.Condition as BinaryExpression;
            if (condition == null)
            {
                return false;
            }

            VariableReferenceExpression conditionLeft = condition.Left as VariableReferenceExpression;
            if (conditionLeft == null)
            {
                return false;
            }

            LiteralExpression conditionRight = condition.Right as LiteralExpression;
            if (conditionRight == null)
            {
                return false;
            }

            if (!conditionLeft.Equals(variableReference) || conditionRight.Value != null ||
                (condition.Operator != BinaryOperator.ValueEquality && condition.Operator != BinaryOperator.ValueInequality))
            {
                return false;
            }

            // At this point we know the type of the exception
            VariableDefinition variableDefinition = variableReference.Variable.Resolve();
            IEnumerable<Instruction> instructions = variableReference.MappedInstructions;

            BlockStatement exceptionVariableAssignmentBlock;
            if (condition.Operator == BinaryOperator.ValueInequality)
            {
                exceptionVariableAssignmentBlock = ifStatement.Then;
            }
            else // BinaryOperator.ValueEquality
            {
                exceptionVariableAssignmentBlock = ifStatement.Else;
            }

            ExpressionStatement expressionStatement = exceptionVariableAssignmentBlock.Statements[0] as ExpressionStatement;
            if (!TryGetVariableDeclaration(expressionStatement, variableReference, ref variableDefinition, ref instructions))
            {
                if (exceptionVariableAssignmentBlock.Statements.Count >= 2)
                {
                    expressionStatement = exceptionVariableAssignmentBlock.Statements[1] as ExpressionStatement;
                    TryGetVariableDeclaration(expressionStatement, variableReference, ref variableDefinition, ref instructions);
                }
            }

            variableDeclaration = new VariableDeclarationExpression(variableDefinition, instructions);

            return true;
        }
 public virtual void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
 }
 public override Expression CloneExpressionOnly()
 {
     VariableDeclarationExpression result = new VariableDeclarationExpression(Variable, null);
     return result;
 }
 public override ICodeNode VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     this.decompilationContext.MethodContext.VariablesToRename.Add(node.Variable);
     return base.VisitVariableDeclarationExpression(node);
 }
        public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
        {
            if (!methodContext.VariableDefinitionToNameMap.ContainsKey(node.Variable))
            {
                methodContext.VariableDefinitionToNameMap.Add(node.Variable, node.Variable.Name);
            }

            if (state == State.SearchForPossibleNames)
            {
                SuggestNameForVariable(node.Variable);
            }
            else if (state == State.RenameVariables)
            {
                TryRenameVariable(node.Variable);
            }

            base.VisitVariableDeclarationExpression(node);
        }
        private void CreateMethod(CatchClause catchClause, VariableDeclarationExpression variable, out Expression methodInvocationExpression)
        {
            methodInvocationExpression = null;

            BlockStatement filter = catchClause.Filter as BlockStatement;

            // Fixes the variable definition in the first statement.
            ExpressionStatement firstStatement = filter.Statements.First() as ExpressionStatement;
            BinaryExpression assignment = firstStatement.Expression as BinaryExpression;
            SafeCastExpression safeCast = assignment.Right as SafeCastExpression;
            VariableReferenceExpression variableReference = safeCast.Expression as VariableReferenceExpression;
            variableReference.Variable = variable.Variable;

            // Replace the variable reference in the last statement with return statement.
            ExpressionStatement lastStatement = filter.Statements.Last() as ExpressionStatement;
            lastStatement.Expression = new ReturnExpression(lastStatement.Expression, lastStatement.Expression.MappedInstructions);

            int methodNumber = this.context.TypeContext.GeneratedFilterMethods.Count + this.methodsToBeDecompiled.Count;
            string methodName = string.Format(Constants.JustDecompileGeneratedFilterPattern, methodNumber);
            MethodDefinition method = new MethodDefinition(methodName, Mono.Cecil.MethodAttributes.Private, this.context.MethodContext.Method.Module.TypeSystem.Boolean);
            method.Body = new MethodBody(method);
            // Practically no chance for duplicates, because of decrementing the MaxRID
            method.MetadataToken = new MetadataToken(TokenType.Method, MaxRID - (uint)methodNumber);
            method.IsStatic = this.context.MethodContext.Method.IsStatic;
            method.HasThis = !method.IsStatic;
            method.DeclaringType = context.MethodContext.Method.DeclaringType;
            method.SemanticsAttributes = MethodSemanticsAttributes.None;
            method.IsJustDecompileGenerated = true;

            DecompilationContext newContext = new DecompilationContext(CloneAndReplaceMethodBody(this.context.MethodContext, method.Body), this.context.TypeContext);

            VariableDefinition variableDefinition = variableReference.Variable.Resolve();
            if (!newContext.MethodContext.VariableDefinitionToNameMap.ContainsKey(variableDefinition))
            {
                newContext.MethodContext.VariableDefinitionToNameMap[variableDefinition] = Constants.JustDecompileGeneratedException;
            }
            else
            {
                newContext.MethodContext.VariableDefinitionToNameMap.Add(variableDefinition, Constants.JustDecompileGeneratedException);
            }

            newContext.MethodContext.VariablesToNotDeclare.Add(variable.Variable);

            methodsToBeDecompiled.Add(new FilterMethodToBeDecompiled(method, catchClause, newContext, catchClause.Filter as BlockStatement));

            List<Expression> parameters = AddAllParameters(catchClause, method, variable);
            methodInvocationExpression = CreateMethodInvocation(method, parameters);
        }
        public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
        {
            if ((node.Variable.VariableType.IsOptionalModifier || node.Variable.VariableType.IsRequiredModifier) &&
                !this.isWritingComment)
            {
                StartWritingComment();
                VisitVariableDeclarationExpression(node);
                EndWritingComment();
                WriteLine();
            }

            WriteDim();

            VariableDefinition variable = node.Variable;
            if (variable.VariableType.ContainsAnonymousType())
            {
                WriteToken(GetVariableName(variable));
            }
            else
            {
                base.VisitVariableDeclarationExpression(node);
            }
        }
        private List<Expression> AddAllParameters(CatchClause catchClause, MethodDefinition method, VariableDeclarationExpression variable)
        {
            List<Expression> methodInvocationArguments = new List<Expression>();

            method.Parameters.Add(CreateParameter(Constants.JustDecompileGeneratedException, variable.Variable.VariableType));
            methodInvocationArguments.Add(new UnaryExpression(UnaryOperator.AddressReference, new VariableReferenceExpression(variable.Variable, null), null));

            if (this.catchClausesUsedVariablesMap.ContainsKey(catchClause))
            {
                foreach (VariableDefinition variableDefinition in this.catchClausesUsedVariablesMap[catchClause])
                {
                    if (variablesUsedOutsideFilters.Contains(variableDefinition) && variableDefinition != variable.Variable)
                    {
                        // If parameter's name is null, it will be ranamed in RenameVariables step.
                        string parameterName = context.MethodContext.VariablesToRename.Contains(variableDefinition) ? null : variableDefinition.Name;
                        ParameterDefinition parameter = CreateParameter(parameterName, variableDefinition.VariableType);
                        if (parameterName == null)
                        {
                            if (!catchClausesVariablesToParametersMap.ContainsKey(catchClause))
                            {
                                catchClausesVariablesToParametersMap.Add(catchClause, new Dictionary<VariableDefinition, ParameterDefinition>());
                            }

                            catchClausesVariablesToParametersMap[catchClause].Add(variableDefinition, parameter);
                        }
                        
                        method.Parameters.Add(parameter);
                        methodInvocationArguments.Add(new UnaryExpression(UnaryOperator.AddressReference, new VariableReferenceExpression(variableDefinition, null), null));
                    }
                }
            }

            if (this.catchClausesUsedParametersMap.ContainsKey(catchClause))
            {
                foreach (ParameterDefinition parameterDefinition in this.catchClausesUsedParametersMap[catchClause])
                {
                    method.Parameters.Add(CreateParameter(parameterDefinition.Name, parameterDefinition.ParameterType));
                    methodInvocationArguments.Add(new UnaryExpression(UnaryOperator.AddressReference, new ArgumentReferenceExpression(parameterDefinition, null), null));
                }
            }
            
            return methodInvocationArguments;
        }
        public override ICodeNode VisitVariableDeclarationExpression(VariableDeclarationExpression node)
        {
            TryDiscardVariable(node.Variable);

            return node;
        }
 public override ICodeNode VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     AddReferencedVariable(node.Variable.Resolve());
     return node;
 }
        public override Expression CloneExpressionOnly()
        {
            VariableDeclarationExpression result = new VariableDeclarationExpression(Variable, null);

            return(result);
        }
 public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     if (this.Language.GetType() != typeof(CSharp))
     {
         string variableName = GetVariableName(node.Variable);
         if (node.Variable.VariableType.ContainsAnonymousType())
         {
             WriteKeyword(KeyWordWriter.Dim);
             WriteSpace();
             Write(variableName);
         }
         else if (node.Variable.Resolve().IsDynamic)
         {
             WriteDynamicType(node.Variable.VariableType, node.Variable.DynamicPositioningFlags);
             WriteSpace();
             Write(variableName);
         }
         else
         {
             base.VisitVariableDeclarationExpression(node);
         }
     }
     else
     {
         base.VisitVariableDeclarationExpression(node);
     }
 }
		public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
		{
			VariableDefinition variable = node.Variable;
			WriteTypeAndName(variable.VariableType, GetVariableName(variable));
		}
 public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     WriteTypeAndName(node.Variable.VariableType, node.Variable.Name);
 }
 public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     if (node.Variable == oldVariable)
     {
         node.Variable = newVariable;
     }
 }
 public override void VisitVariableDeclarationExpression(VariableDeclarationExpression node)
 {
     RemoveVariable(node.Variable.Resolve());
 }