public VariableInliningPattern(CodePatternsContext patternsContext, MethodSpecificContext methodContext, IVariablesToNotInlineFinder finder)
     : base(patternsContext, methodContext.Method.Module.TypeSystem)
 {
     this.methodContext = methodContext;
     this.inliner       = new RestrictedVariableInliner(typeSystem);
     this.finder        = finder;
 }
            public override ICodeNode VisitObjectCreationExpression(ObjectCreationExpression node)
            {
                if (state == State.ReplaceDelegate && node.Arguments != null && node.Arguments.Count == 2 &&
                    node.Arguments[0].CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                    node.Arguments[1].CodeNodeType == CodeNodeType.MethodReferenceExpression &&
                    delegateCopies.Contains((node.Arguments[0] as VariableReferenceExpression).Variable))
                {
                    //final check inserted here for optimization
                    TypeDefinition objectType = node.Constructor.DeclaringType.Resolve();
                    if (objectType == null || objectType.BaseType == null || objectType.BaseType.FullName != "System.MulticastDelegate")
                    {
                        return(base.VisitObjectCreationExpression(node));
                    }

                    MethodReference  methodReference  = (node.Arguments[1] as MethodReferenceExpression).Method;
                    MethodDefinition methodDefinition = (node.Arguments[1] as MethodReferenceExpression).MethodDefinition;

                    MethodSpecificContext delegateMethodContext = new MethodSpecificContext(methodDefinition.Body);
                    DecompilationContext  innerContext          = new DecompilationContext(delegateMethodContext, context.TypeContext, context.ModuleContext, context.AssemblyContext);
                    delegateMethodContext.FieldToExpression = fieldDefToAssignedValueMap;

                    BlockStatement methodStatements = methodDefinition.Body.DecompileLambda(Language, innerContext);

                    if ((methodStatements.Statements.Count == 1) && (methodStatements.Statements[0].CodeNodeType == CodeNodeType.ExpressionStatement) &&
                        ((methodStatements.Statements[0] as ExpressionStatement).Expression.CodeNodeType == CodeNodeType.ReturnExpression))
                    {
                        ReturnExpression          returnExpression          = (methodStatements.Statements[0] as ExpressionStatement).Expression as ReturnExpression;
                        ShortFormReturnExpression shortFormReturnExpression = new ShortFormReturnExpression(returnExpression.Value, returnExpression.MappedInstructions);
                        methodStatements = new BlockStatement();
                        methodStatements.Statements.Add(new ExpressionStatement(shortFormReturnExpression));
                    }

                    this.context.MethodContext.VariableDefinitionToNameMap.AddRange(innerContext.MethodContext.VariableDefinitionToNameMap);
                    this.context.MethodContext.VariableNamesCollection.UnionWith(innerContext.MethodContext.VariableNamesCollection);
                    this.context.MethodContext.AddInnerMethodParametersToContext(innerContext.MethodContext);
                    this.context.MethodContext.GotoStatements.AddRange(innerContext.MethodContext.GotoStatements);
                    this.context.MethodContext.GotoLabels.AddRange(innerContext.MethodContext.GotoLabels);

                    ExpressionCollection expressionCollection = new ExpressionCollection();
                    bool hasAnonymousParamterer = LambdaExpressionsHelper.HasAnonymousParameter(methodDefinition.Parameters);
                    foreach (ParameterDefinition parameter in methodDefinition.Parameters)
                    {
                        expressionCollection.Add(new LambdaParameterExpression(parameter, !hasAnonymousParamterer, null));
                    }

                    delegatesFound.Add(methodStatements);

                    LambdaExpression lambdaExpression =
                        new LambdaExpression(expressionCollection, methodStatements, methodDefinition.IsAsync(), methodDefinition.IsFunction(), methodReference.Parameters, false,
                                             node.Arguments[1].MappedInstructions)
                    {
                        ExpressionType = objectType
                    };

                    DelegateCreationExpression result = new DelegateCreationExpression(node.Constructor.DeclaringType, lambdaExpression, node.Arguments[0], node.MappedInstructions);
                    return(result);
                }

                return(base.VisitObjectCreationExpression(node));
            }
Example #3
0
 public Ast.Statements.BlockStatement Process(Decompiler.DecompilationContext context, Ast.Statements.BlockStatement body)
 {
     this.methodContext = context.MethodContext;
     mappedInstructions.UnionWith(body.UnderlyingSameMethodInstructions);
     Visit(body);
     return(body);
 }
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     this.context = context.get_MethodContext();
     V_0          = context.get_MethodContext().get_Expressions().get_BlockExpressions().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             this.parentExpressions.Clear();
             V_2 = V_1.get_Value().GetEnumerator();
             try
             {
                 while (V_2.MoveNext())
                 {
                     V_3 = V_2.get_Current();
                     this.Visit(V_3);
                 }
             }
             finally
             {
                 if (V_2 != null)
                 {
                     V_2.Dispose();
                 }
             }
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return(body);
 }
        private BlockStatement body;///This is left to make debugging easier

        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            this.methodContext = context.MethodContext;
            this.body          = body;
            RemoveGotoStatements();
            return(body);
        }
Example #6
0
 public DecompilationContext(MethodSpecificContext methodContext, TypeSpecificContext typeContext, ModuleSpecificContext moduleContext, AssemblySpecificContext assemblyContext)
 {
     this.MethodContext   = methodContext;
     this.TypeContext     = typeContext;
     this.ModuleContext   = moduleContext;
     this.AssemblyContext = assemblyContext;
 }
        /// <summary>
        /// The entry point for the step.
        /// </summary>
        /// <param name="context">The decompilation context.</param>
        /// <param name="body">The body of the method.</param>
        /// <returns>Returns the updated body of the method.</returns>
        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            MethodSpecificContext methodContext = context.MethodContext;

            foreach (int key in methodContext.Expressions.BlockExpressions.Keys)
            {
                IList <Expression> expressionList = methodContext.Expressions.BlockExpressions[key];
                Code lastInstructionCode          = methodContext.ControlFlowGraph.InstructionToBlockMapping[key].Last.OpCode.Code;
                bool endsWithConditionalJump      = lastInstructionCode == Code.Brtrue || lastInstructionCode == Code.Brtrue_S ||
                                                    lastInstructionCode == Code.Brfalse || lastInstructionCode == Code.Brfalse_S;
                for (int i = 0; i < expressionList.Count; i++)
                {
                    expressionList[i] = (Expression)Visit(expressionList[i]);
                }
                if (endsWithConditionalJump)
                {
                    expressionList[expressionList.Count - 1] = (Expression)
                                                               FixBranchingExpression(expressionList[expressionList.Count - 1], methodContext.ControlFlowGraph.InstructionToBlockMapping[key].Last);
                }
                //if (lastInstructionCode == Code.Switch)
                //{
                //    //the type of this expression is needed if the switch instruction causes IrregularSwitchLC
                //    //so that correct expressions can be produced for case's conditions
                //    //Expression lastExpression = expressionList[expressionList.Count - 1];
                //}
            }
            return(body);
        }
 public UsedAsTypeHelper(MethodSpecificContext methodContext)
 {
     base();
     this.methodContext = methodContext;
     this.typeSystem    = methodContext.get_Method().get_Module().get_TypeSystem();
     return;
 }
 public StateControllerRemover(MethodSpecificContext methodContext, FieldDefinition stateField = null)
 {
     this.methodContext     = methodContext;
     this.theCFG            = methodContext.ControlFlowGraph;
     this.stateField        = stateField;
     this.stateToStartBlock = new InstructionBlock[this.theCFG.Blocks.Length];
 }
Example #10
0
 public MultiAssignPattern(CodePatternsContext patternsContext, MethodSpecificContext methodContext)
 {
     this.variablesToRemove = new HashSet <VariableDefinition>();
     base(patternsContext, methodContext.get_Method().get_Module().get_TypeSystem());
     this.methodContext = methodContext;
     return;
 }
 private MethodSpecificContext CloneAndReplaceMethodBody(MethodSpecificContext context, MethodBody methodBody)
 {
     return(new MethodSpecificContext(context.AnalysisResults,
                                      context.YieldData,
                                      context.AsyncData,
                                      context.IsMethodBodyChanged,
                                      new Dictionary <string, Statement>(context.GotoLabels),
                                      new List <GotoStatement>(context.GotoStatements),
                                      context.StackData,
                                      context.IsBaseConstructorInvokingConstructor,
                                      context.EnableEventAnalysis,
                                      methodBody,
                                      new Collection <VariableDefinition>(context.Variables),
                                      context.ControlFlowGraph,
                                      context.Expressions,
                                      context.LogicalConstructsTree,
                                      context.LogicalConstructsContext,
                                      context.CtorInvokeExpression,
                                      new Dictionary <Statement, ILogicalConstruct>(context.StatementToLogicalConstruct),
                                      new Dictionary <ILogicalConstruct, List <Statement> >(context.LogicalConstructToStatements),
                                      new Dictionary <VariableDefinition, string>(context.VariableDefinitionToNameMap),
                                      new HashSet <string>(context.VariableNamesCollection),
                                      new Dictionary <ParameterDefinition, string>(context.ParameterDefinitionToNameMap),
                                      new HashSet <VariableDefinition>(context.VariablesToRename),
                                      new Dictionary <FieldDefinition, Expression>(context.FieldToExpression),
                                      context.LambdaVariablesCount,
                                      new Dictionary <VariableDefinition, AssignmentType>(context.VariableAssignmentData),
                                      new List <ParameterDefinition>(context.OutParametersToAssign),
                                      context.IsDestructor,
                                      context.DestructorStatements,
                                      new HashSet <VariableDefinition>(context.UndeclaredLinqVariables),
                                      new Dictionary <VariableReference, Dictionary <FieldDefinition, Expression> >(context.ClosureVariableToFieldValue),
                                      new HashSet <VariableDefinition>(context.VariablesToNotDeclare)));
 }
 public StateControllerRemover(MethodSpecificContext methodContext, FieldDefinition stateField = null)
 {
     this.methodContext = methodContext;
     this.theCFG = methodContext.ControlFlowGraph;
     this.stateField = stateField;
     this.stateToStartBlock = new InstructionBlock[this.theCFG.Blocks.Length];
 }
 public LinqQueriesRebuilder(MethodSpecificContext methodContext)
 {
     this.clauses = new List <QueryClause>();
     base();
     this.methodContext = methodContext;
     return;
 }
 public StackVariablesInliner(MethodSpecificContext methodContext, Dictionary <int, Expression> offsetToExpression, IVariablesToNotInlineFinder finder)
 {
     this.inlinedOnSecondPass = new HashSet <VariableDefinition>();
     base(methodContext, new SimpleVariableInliner(methodContext.get_Method().get_Module().get_TypeSystem()), finder);
     this.offsetToExpression = offsetToExpression;
     return;
 }
		public DecompilationContext(MethodSpecificContext methodContext, TypeSpecificContext typeContext, ModuleSpecificContext moduleContext, AssemblySpecificContext assemblyContext)
		{
			this.MethodContext = methodContext;
			this.TypeContext = typeContext;
			this.ModuleContext = moduleContext;
			this.AssemblyContext = assemblyContext;
		}
Example #16
0
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     this.methodContext = context.get_MethodContext();
     this.mappedInstructions.UnionWith(body.get_UnderlyingSameMethodInstructions());
     this.Visit(body);
     return(body);
 }
Example #17
0
 public AsyncStateControllerRemover(MethodSpecificContext methodContext, FieldDefinition stateField, VariableReference doFinallyVariable, AsyncStateMachineVersion version)
 {
     base(methodContext, stateField);
     this.doFinallyVariable = doFinallyVariable;
     this.version           = version;
     return;
 }
        private BlockStatement body;///This is left to make debugging easier

        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            this.methodContext = context.MethodContext;
            this.body = body;
            RemoveGotoStatements();
            return body;
        }
        protected MethodSpecificContext GetMethodContext(IMemberDefinition member)
        {
            string memberFullName = Utilities.GetMemberUniqueName(member);
            MethodSpecificContext methodContext;
            MethodSpecificContext result = this.writerContext.MethodContexts.TryGetValue(memberFullName, out methodContext) ? methodContext : null;

            return(result);
        }
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     this.methodContext = context.MethodContext;
     ClearState();
     this.foreachBody = new BlockStatement();
     Visit(body);
     return(body);
 }
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     this.methodContext = context.get_MethodContext();
     this.Visit(body);
     body = CallSiteInvocationReplacer.ReplaceInvocations(body, this.fieldToCallSiteInfoMap, this.variableToCallSiteInfoMap, this.statementsToRemove, this.methodContext.get_Method().get_Module().get_TypeSystem());
     this.RemoveStatements();
     return(body);
 }
        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            this.methodContext = context.MethodContext;

            Visit(body);

            return(body);
        }
Example #23
0
 public StateMachineFinallyCheckRemoverBase(MethodSpecificContext methodContext)
 {
     this.toBeRemoved = new HashSet <InstructionBlock>();
     base();
     this.methodVariables = methodContext.get_Body().get_Variables();
     this.theCFG          = methodContext.get_ControlFlowGraph();
     return;
 }
Example #24
0
 public ForeachArrayMatcher(Statement statement, Statement nextStatement, MethodSpecificContext methodContext)
 {
     base();
     this.statement     = statement;
     this.nextStatement = nextStatement;
     this.methodContext = methodContext;
     return;
 }
 public BlockStatement Process(DecompilationContext context, BlockStatement block)
 {
     this.methodContext = context.get_MethodContext();
     this.PopulateNotAssigned();
     this.codeNodeTypes.Push(0);
     dummyVar0 = this.VisitBlockStatement(block);
     dummyVar1 = this.codeNodeTypes.Pop();
     return(this.ReplaceDeclarations(block));
 }
 public YieldGuardedBlocksBuilder(LogicalFlowBuilderContext logicalContext, DecompilationContext decompilationContext)
 {
     this.orderedCFGNodes = new List <CFGBlockLogicalConstruct>();
     this.createdConstructsToIntervalMap = new Dictionary <TryFinallyLogicalConstruct, YieldExceptionHandlerInfo>();
     base();
     this.logicalContext = logicalContext;
     this.methodContext  = decompilationContext.get_MethodContext();
     return;
 }
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     methodContext = context.MethodContext;
     Visit(body);
     body = CallSiteInvocationReplacer.ReplaceInvocations(body, fieldToCallSiteInfoMap, variableToCallSiteInfoMap, statementsToRemove,
                                                          methodContext.Method.Module.TypeSystem);
     RemoveStatements();
     return(body);
 }
 public VariableInliningPattern(CodePatternsContext patternsContext, MethodSpecificContext methodContext, IVariablesToNotInlineFinder finder)
 {
     base(patternsContext, methodContext.get_Method().get_Module().get_TypeSystem());
     this.methodContext = methodContext;
     this.inliner       = new RestrictedVariableInliner(this.typeSystem);
     this.finder        = finder;
     this.dereferencer  = new SimpleDereferencer();
     return;
 }
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     this.methodContext             = context.get_MethodContext();
     this.blockExpressions          = this.methodContext.get_Expressions().get_BlockExpressions();
     this.instructionToBlockMapping = this.methodContext.get_ControlFlowGraph().get_InstructionToBlockMapping();
     this.blocksToBeRemoved         = new List <int>();
     this.switchBlocksToCasesMap    = this.methodContext.get_SwitchByStringData().get_SwitchBlocksToCasesMap();
     this.RemoveSwitchByStringOptimizations();
     return(body);
 }
 public StateControllerRemover(MethodSpecificContext methodContext, FieldDefinition stateField = null)
 {
     this.toBeRemoved = new HashSet <InstructionBlock>();
     base();
     this.methodContext     = methodContext;
     this.theCFG            = methodContext.get_ControlFlowGraph();
     this.stateField        = stateField;
     this.stateToStartBlock = new InstructionBlock[(int)this.theCFG.get_Blocks().Length];
     return;
 }
 public ClassHierarchyBuilder(Dictionary<int, Expression> offsetToExpression, Dictionary<int, Instruction> offsetToInstruction, DecompilationContext context)
 {
     this.typeNameToNode = new Dictionary<string, ClassHierarchyNode>();
     this.variableNameToNode = new Dictionary<string, ClassHierarchyNode>();
     this.resultingGraph = new HashSet<ClassHierarchyNode>();
     this.offsetToExpression = offsetToExpression;
     this.offsetToInstruction = offsetToInstruction;
     this.methodContext = context.MethodContext;
     this.typeSystem = context.MethodContext.Method.Module.TypeSystem;
 }
Example #32
0
 public ClassHierarchyBuilder(Dictionary <int, Expression> offsetToExpression, Dictionary <int, Instruction> offsetToInstruction, DecompilationContext context)
 {
     this.typeNameToNode      = new Dictionary <string, ClassHierarchyNode>();
     this.variableNameToNode  = new Dictionary <string, ClassHierarchyNode>();
     this.resultingGraph      = new HashSet <ClassHierarchyNode>();
     this.offsetToExpression  = offsetToExpression;
     this.offsetToInstruction = offsetToInstruction;
     this.methodContext       = context.MethodContext;
     this.typeSystem          = context.MethodContext.Method.Module.TypeSystem;
 }
 public BaseVariablesInliner(MethodSpecificContext methodContext, IVariableInliner inliner, IVariablesToNotInlineFinder finder)
 {
     this.variablesToNotInline = new HashSet <VariableDefinition>();
     this.variablesToInline    = new HashSet <VariableDefinition>();
     base();
     this.methodContext = methodContext;
     this.inliner       = inliner;
     this.finder        = finder;
     return;
 }
Example #34
0
        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            this.methodContext      = context.MethodContext;
            this.originalStatements = body.Statements;
            if (Match())
            {
                body.Statements = asyncStatements;
            }

            return(body);
        }
        public AsyncMoveNextMethodAnalyzer(MethodSpecificContext moveNextMethodContext, FieldDefinition stateField)
        {
            this.theCFG = moveNextMethodContext.ControlFlowGraph;
            this.methodVariables = moveNextMethodContext.Variables;
            this.stateField = stateField;

            if (GetDoFinallyVariable())
            {
                this.StateMachineVersion = AsyncStateMachineVersion.V1;
            }
            else
            {
                GetStateVariable();
                this.StateMachineVersion = AsyncStateMachineVersion.V2;
            }
        }
        /// <summary>
        /// The entry point for the class.
        /// </summary>
        /// <param name="context">The decompilation context.</param>
        /// <param name="body">The body of the method.</param>
        /// <returns>Returns the updated body of the method.</returns>
        public BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            this.methodContext = context.MethodContext;
            this.controlFlowGraph = this.methodContext.ControlFlowGraph;
            this.exceptionHandlers = controlFlowGraph.RawExceptionHandlers;
            this.blockToInitialStackMap = new int[controlFlowGraph.Blocks.Length][];
            this.blockToExitStackMap = new int[controlFlowGraph.Blocks.Length][];

            /// Perform the analysis.
            AnalyzeStackUsage();

            GenerateStackVariables();

            GenerateStackData();

            return body;
        }
        /// <summary>
        /// The entry point of the step.
        /// </summary>
        /// <param name="context">The decompilation context for the current method.</param>
        /// <param name="body">The body of the current method.</param>
        /// <returns>Returns the updated body of the current method.</returns>
        public virtual BlockStatement Process(DecompilationContext context, BlockStatement body)
        {
            this.methodContext = context.MethodContext;
            this.typeSystem = methodContext.Method.Module.TypeSystem;
            this.body = body;
            RemoveGotoStatements();

            methodContext.Variables.AddRange(switchVariables);
            methodContext.VariablesToRename.UnionWith(switchVariables);

            methodContext.Variables.AddRange(labelToVariable.Values);
            methodContext.VariablesToRename.UnionWith(labelToVariable.Values);

            CleanupUnneededVariables();

            AddDefaultAssignmentsToNewConditionalVariables(body);

            return body;
        }
		public BlockStatement Process(DecompilationContext context, BlockStatement body)
		{
			this.methodContext = context.MethodContext;
            TypeSystem typeSystem = context.MethodContext.Method.Module.TypeSystem;

			logicalBuilderContext = new LogicalFlowBuilderContext(context.MethodContext.ControlFlowGraph);
            cfgBlockSplitter = new CFGBlockSplitter(logicalBuilderContext);
			conditionBuilder = new ConditionBuilder(logicalBuilderContext, typeSystem);
			loopBuilder = new LoopBuilder(logicalBuilderContext, typeSystem);
			switchBuilder = new SwitchBuilder(logicalBuilderContext);
			ifBuilder = new IfBuilder(logicalBuilderContext, methodContext.Method.Module.TypeSystem);
            followNodeDeterminator = new FollowNodeDeterminator(typeSystem);
            yieldGuardedBlocksBuilder = new YieldGuardedBlocksBuilder(logicalBuilderContext, context);

            GetMaxIndexOfBlock();
			InitializeTheBlock();
            
			guardedBlocksBuilder = new GuardedBlocksBuilder(logicalBuilderContext);

			context.MethodContext.LogicalConstructsTree = BuildLogicalConstructTree();
			context.MethodContext.LogicalConstructsContext = logicalBuilderContext;

			return body;
		}
 public MethodVariablesInliningStep(MethodSpecificContext methodContext)
     : base(methodContext, new RestrictedVariableInliner(methodContext.Method.Module.TypeSystem))
 {
 }
 public DisposingStateControllerRemover(MethodSpecificContext methodContext, FieldDefinition stateField, FieldDefinition disposingField)
     :base(methodContext, stateField)
 {
     this.disposingField = disposingField;
 }
		public DecompilationContext(MethodSpecificContext methodContext, TypeSpecificContext typeContext)
			: this(methodContext, typeContext, new ModuleSpecificContext(), new AssemblySpecificContext())
		{
		}
 public YieldGuardedBlocksBuilder(LogicalFlowBuilderContext logicalContext, DecompilationContext decompilationContext)
 {
     this.logicalContext = logicalContext;
     this.methodContext = decompilationContext.MethodContext;
 }
 public BaseVariableInliningStep(MethodSpecificContext methodContext, IVariableInliner inliner)
 {
     this.methodContext = methodContext;
     this.inliner = inliner;
 }
 public YieldStateMachineControlFlowRebuilder(MethodSpecificContext moveNextMethodContext, SwitchData controllerSwitchData, FieldDefinition stateField)
 {
     this.moveNextMethodContext = moveNextMethodContext;
     this.switchData = controllerSwitchData;
     this.stateField = stateField;
 }
 public MethodVariablesInliner(MethodSpecificContext methodContext, IVariablesToNotInlineFinder finder)
     : base(methodContext, new RestrictedVariableInliner(methodContext.Method.Module.TypeSystem), finder)
 {
 }
 public StateMachineFinallyStateCheckRemover(MethodSpecificContext moveNextMethodContext)
     : base(moveNextMethodContext)
 {
 }
 public StateMachineFinallyCheckRemoverBase(MethodSpecificContext methodContext)
 {
     this.methodVariables = methodContext.Body.Variables;
     this.theCFG = methodContext.ControlFlowGraph;
 }
 public UsedAsTypeHelper(MethodSpecificContext methodContext)
 {
     this.methodContext = methodContext;
     this.typeSystem = methodContext.Method.Module.TypeSystem;
 }
 public BaseVariablesInliner(MethodSpecificContext methodContext, IVariableInliner inliner, IVariablesToNotInlineFinder finder)
 {
     this.methodContext = methodContext;
     this.inliner = inliner;
     this.finder = finder;
 }
 public StateMachineDoFinallyCheckRemover(MethodSpecificContext methodContext)
     : base(methodContext)
 {
 }
 public AsyncStateControllerRemover(MethodSpecificContext methodContext, FieldDefinition stateField, VariableReference doFinallyVariable, AsyncStateMachineVersion version)
     :base(methodContext, stateField)
 {
     this.doFinallyVariable = doFinallyVariable;
     this.version = version;
 }