private void FindNestedAssignments(AstExpression expr, ExpressionToInfer parent) { foreach (var arg in expr.Arguments) { if (arg.Code == AstCode.Stloc) { var expressionToInfer = new ExpressionToInfer(arg); allExpressions.Add(expressionToInfer); FindNestedAssignments(arg, expressionToInfer); var v = (AstVariable)arg.Operand; if (v.Type == null) { assignmentExpressions[v].Add(expressionToInfer); // the instruction that consumes the stloc result is handled as if it was reading the variable parent.Dependencies.Add(v); } } else { AstVariable v; if (arg.Match(AstCode.Ldloc, out v) && (v.Type == null)) { parent.Dependencies.Add(v); } FindNestedAssignments(arg, parent); } } }
/// <summary> /// Creates the "ExpressionToInfer" instances (=nodes in dependency graph) /// </summary> /// <remarks> /// We are using a dependency graph to ensure that expressions are analyzed in the correct order. /// </remarks> private void CreateDependencyGraph(AstNode node) { var catchBlock = node as AstTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null && catchBlock.ExceptionType != null && catchBlock.ExceptionVariable.Type == null) { catchBlock.ExceptionVariable.Type = catchBlock.ExceptionType; } var expr = node as AstExpression; if (expr != null) { var expressionToInfer = new ExpressionToInfer(expr); allExpressions.Add(expressionToInfer); FindNestedAssignments(expr, expressionToInfer); if ((expr.Code == AstCode.Stloc) && ((AstVariable) expr.Operand).Type == null) { assignmentExpressions[(AstVariable)expr.Operand].Add(expressionToInfer); } return; } foreach (var child in node.GetChildren()) { CreateDependencyGraph(child); } }
/// <summary> /// Creates the "ExpressionToInfer" instances (=nodes in dependency graph) /// </summary> /// <remarks> /// We are using a dependency graph to ensure that expressions are analyzed in the correct order. /// </remarks> void CreateDependencyGraph(ILNode node) { ILCondition cond = node as ILCondition; if (cond != null) { cond.Condition.ExpectedType = typeSystem.Boolean; } ILWhileLoop loop = node as ILWhileLoop; if (loop != null && loop.Condition != null) { loop.Condition.ExpectedType = typeSystem.Boolean; } ILTryCatchBlock.CatchBlock catchBlock = node as ILTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null && catchBlock.ExceptionType != null && catchBlock.ExceptionVariable.Type == null) { catchBlock.ExceptionVariable.Type = catchBlock.ExceptionType; } ILExpression expr = node as ILExpression; if (expr != null) { ExpressionToInfer expressionToInfer = new ExpressionToInfer(); expressionToInfer.Expression = expr; allExpressions.Add(expressionToInfer); FindNestedAssignments(expr, expressionToInfer); if (expr.Code == ILCode.Stloc && ((ILVariable)expr.Operand).Type == null) assignmentExpressions[(ILVariable)expr.Operand].Add(expressionToInfer); return; } foreach (ILNode child in node.GetChildren()) { CreateDependencyGraph(child); } }
void FindNestedAssignments(ILExpression expr, ExpressionToInfer parent) { foreach (ILExpression arg in expr.Arguments) { if (arg.Code == ILCode.Stloc) { ExpressionToInfer expressionToInfer = new ExpressionToInfer(); expressionToInfer.Expression = arg; allExpressions.Add(expressionToInfer); FindNestedAssignments(arg, expressionToInfer); ILVariable v = (ILVariable)arg.Operand; if (v.Type == null) { assignmentExpressions[v].Add(expressionToInfer); // the instruction that consumes the stloc result is handled as if it was reading the variable parent.Dependencies.Add(v); } } else { ILVariable v; if (arg.Match(ILCode.Ldloc, out v) && v.Type == null) { parent.Dependencies.Add(v); } FindNestedAssignments(arg, parent); } } }