public FilterMethodToBeDecompiled(MethodDefinition method, CatchClause catchClause, DecompilationContext context, BlockStatement block) { this.Method = method; this.CatchClause = catchClause; this.Context = context; this.Block = block; }
public FilterMethodToBeDecompiled(MethodDefinition method, Telerik.JustDecompiler.Ast.Statements.CatchClause catchClause, DecompilationContext context, BlockStatement block) { base(); this.set_Method(method); this.set_CatchClause(catchClause); this.set_Context(context); this.set_Block(block); return; }
public RebuildCatchClausesFilterStep() { this.currentCatchClause = null; this.variablesUsedOutsideFilters = new HashSet<VariableDefinition>(); this.catchClausesUsedVariablesMap = new Dictionary<CatchClause, HashSet<VariableDefinition>>(); this.catchClausesUsedParametersMap = new Dictionary<CatchClause, HashSet<ParameterDefinition>>(); this.catchClausesVariablesToParametersMap = new Dictionary<CatchClause, Dictionary<VariableDefinition, ParameterDefinition>>(); this.methodsToBeDecompiled = new List<FilterMethodToBeDecompiled>(); }
private void SetParentToThis(CatchClause catchClause) { if (catchClause.Body != null) { catchClause.Body.Parent = this; } if (catchClause.Filter != null) { catchClause.Filter.Parent = this; } }
public override ICodeNode VisitCatchClause(CatchClause node) { // If we have a catch clause with filter, we need aggressive inlining (only for TernaryConditionPattern) of the filter block, because our pattern matching relies on this. if (node.Filter != null) { this.isInFilter = true; node.Filter = (Statement)Visit(node.Filter); this.isInFilter = false; node.Body = (BlockStatement)Visit(node.Body); return node; } return base.VisitCatchClause(node); }
public override ICodeNode VisitCatchClause(CatchClause node) { // We first visit the body and the filter node.Body = (BlockStatement)base.Visit(node.Body); if (node.Filter == null || !(node.Filter is BlockStatement)) { return node; } currentCatchClause = node; node.Filter = (Statement)base.Visit(node.Filter); currentCatchClause = null; VariableDeclarationExpression variableDeclaration; Expression filterExpression; bool matchSucceed = CatchClausesFilterPattern.TryMatch(node.Filter as BlockStatement, out variableDeclaration, out filterExpression); if (!matchSucceed) { if (variableDeclaration == null || variableDeclaration.ExpressionType.FullName == Constants.Object || !CatchClausesFilterPattern.TryMatchMethodStructure(node.Filter as BlockStatement)) { throw new NotSupportedException("Unsupported structure of filter clause."); } CreateMethod(node, variableDeclaration, out filterExpression); } this.context.MethodContext.VariablesToNotDeclare.Add(variableDeclaration.Variable); node.Variable = variableDeclaration; node.Type = variableDeclaration.ExpressionType; node.Filter = new ExpressionStatement(filterExpression); return node; }
public void AddToCatchClauses(CatchClause catchClause) { SetParentToThis(catchClause); CatchClauses.Add(catchClause); }
public override void VisitCatchClause(CatchClause node) { WriteKeyword(KeyWordWriter.Catch); if (node.Type.FullName != Constants.Object) { WriteSpace(); if (node.Variable != null) { loopStates.Push(StatementState.Catch); Visit(node.Variable); loopStates.Pop(); } else { WriteReferenceAndNamespaceIfInCollision(node.Type); } } if (node.Filter != null) { WriteSpace(); WriteKeyword(KeyWordWriter.When); WriteSpace(); Visit((node.Filter as ExpressionStatement).Expression); } WriteLine(); Visit(node.Body); }
public override void VisitCatchClause(CatchClause node) { WriteKeyword(KeyWordWriter.Catch); if (node.Type.FullName != Constants.Object) { WriteSpace(); WriteSpecialBetweenParenthesis(() => { if (node.Variable != null) Visit(node.Variable); else WriteReferenceAndNamespaceIfInCollision(node.Type); }); } if (node.Filter != null) { WriteSpace(); WriteKeyword(KeyWordWriter.When); WriteSpace(); WriteSpecialBetweenParenthesis((node.Filter as ExpressionStatement).Expression); } WriteLine(); Visit(node.Body); }
private void AddVariablesToNotDeclare(DecompilationContext context, CatchClause currentCatch) { foreach (VariableDefinition variable in context.MethodContext.Variables) { if (variablesUsedOutsideFilters.Contains(variable)) { context.MethodContext.VariablesToNotDeclare.Add(variable); } foreach (KeyValuePair<CatchClause, HashSet<VariableDefinition>> map in catchClausesUsedVariablesMap) { if (map.Key.Equals(currentCatch)) { continue; } if (map.Value.Contains(variable)) { context.MethodContext.VariablesToNotDeclare.Add(variable); } } } }
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; }
/// <summary> /// This method fixes all variables names that reffer to nameless parameter. /// </summary> private void FixVariablesNames(DecompilationContext innerContext, CatchClause currentCatch) { if (catchClausesVariablesToParametersMap.ContainsKey(currentCatch)) { foreach (KeyValuePair<VariableDefinition, ParameterDefinition> pair in catchClausesVariablesToParametersMap[currentCatch]) { innerContext.MethodContext.VariableDefinitionToNameMap[pair.Key] = innerContext.MethodContext.ParameterDefinitionToNameMap[pair.Value]; } } }
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 virtual void VisitCatchClause(CatchClause node) { Visit(node.Body); Visit(node.Variable); Visit(node.Filter); }