Skip to content

Commit f0c0bd0

Browse files
committed
merge declaration & assignment, support out/ref
1 parent cd22406 commit f0c0bd0

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed

ExpressionDebugger/DebugInfoInjector.cs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -543,13 +543,27 @@ IEnumerable<Expression> VisitBlockBody(IList<Expression> exprs, bool shouldRetur
543543

544544
Expression VisitBlock(BlockExpression node, bool shouldReturn)
545545
{
546+
var assignedVariables = new HashSet<ParameterExpression>(node.Expressions
547+
.Where(exp => exp.NodeType == ExpressionType.Assign)
548+
.Select(exp => ((BinaryExpression)exp).Left)
549+
.Where(exp => exp.NodeType == ExpressionType.Parameter)
550+
.Select(exp => (ParameterExpression)exp));
551+
546552
var list = new List<ParameterExpression>();
553+
var hasDeclaration = false;
547554
foreach (var variable in node.Variables)
548555
{
549-
var arg = VisitNextLine(Translate(variable.Type) + " ", variable, ";");
556+
Expression arg;
557+
if (assignedVariables.Contains(variable))
558+
arg = VisitParameter(variable, false);
559+
else
560+
{
561+
arg = VisitNextLine(Translate(variable.Type) + " ", variable, ";");
562+
hasDeclaration = true;
563+
}
550564
list.Add((ParameterExpression)arg);
551565
}
552-
if (node.Variables.Count > 0)
566+
if (hasDeclaration)
553567
WriteLine();
554568

555569
var lines = VisitBlockBody(node.Expressions, shouldReturn && node.Type != typeof (void));
@@ -664,7 +678,7 @@ protected override Expression VisitConstant(ConstantExpression node)
664678
if (type.GetTypeInfo().IsPrimitive || type == typeof(decimal))
665679
Write(value.ToString());
666680
else
667-
Write("valueof(", Translate(type), ", \"", value.ToString(), "\")");
681+
Write("valueof(", Translate(type), ")");
668682
}
669683

670684
if (_document == null || CanEmitConstant(value, node.Type))
@@ -811,7 +825,7 @@ protected override Expression VisitDynamic(DynamicExpression node)
811825
}
812826
#endif
813827

814-
IList<T> VisitArguments<T>(string open, IList<T> args, Func<T, T> func, string end, bool wrap = false) where T : class
828+
IList<T> VisitArguments<T>(string open, IList<T> args, Func<T, T> func, string end, bool wrap = false, IList<string> prefix = null) where T : class
815829
{
816830
Write(open);
817831
if (wrap)
@@ -824,6 +838,8 @@ IList<T> VisitArguments<T>(string open, IList<T> args, Func<T, T> func, string e
824838
{
825839
if (wrap)
826840
WriteLine();
841+
if (prefix != null)
842+
Write(prefix[i]);
827843
var arg = func(args[i]);
828844
changed |= arg != args[i];
829845
list.Add(arg);
@@ -1142,16 +1158,18 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
11421158
if (node.Method.DeclaringType != null)
11431159
Write(".");
11441160
Write(node.Method.Name);
1161+
var prefix = node.Method.GetParameters()
1162+
.Select(p => p.IsOut ? "out " : p.ParameterType.IsByRef ? "ref " : "");
11451163

11461164
if (isExtension)
11471165
{
1148-
var args = VisitArguments("(", node.Arguments.Skip(1).ToList(), Visit, ")");
1166+
var args = VisitArguments("(", node.Arguments.Skip(1).ToList(), Visit, ")", prefix: prefix.Skip(1).ToList());
11491167
var newArgs = new[] {arg0}.Concat(args).ToList();
11501168
return newArgs.SequenceEqual(node.Arguments) ? node : node.Update(obj, newArgs);
11511169
}
11521170
else
11531171
{
1154-
var args = VisitArguments("(", node.Arguments, Visit, ")");
1172+
var args = VisitArguments("(", node.Arguments, Visit, ")", prefix: prefix.ToList());
11551173
return node.Update(obj, args);
11561174
}
11571175
}
@@ -1274,8 +1292,28 @@ protected override Expression VisitNewArray(NewArrayExpression node)
12741292

12751293
protected override Expression VisitParameter(ParameterExpression node)
12761294
{
1295+
return VisitParameter(node, true);
1296+
}
1297+
1298+
HashSet<ParameterExpression> _pendingVariables;
1299+
private Expression VisitParameter(ParameterExpression node, bool write)
1300+
{
1301+
if (_pendingVariables == null)
1302+
_pendingVariables = new HashSet<ParameterExpression>();
1303+
12771304
var name = GetName(node);
1278-
Write(name);
1305+
if (write)
1306+
{
1307+
if (_pendingVariables.Contains(node))
1308+
{
1309+
Write(Translate(node.Type), " ", name);
1310+
_pendingVariables.Remove(node);
1311+
}
1312+
else
1313+
Write(name);
1314+
}
1315+
else
1316+
_pendingVariables.Add(node);
12791317

12801318
if (!string.IsNullOrEmpty(node.Name))
12811319
return node;
@@ -1412,7 +1450,8 @@ protected override Expression VisitUnary(UnaryExpression node)
14121450
{
14131451
case ExpressionType.Convert:
14141452
case ExpressionType.ConvertChecked:
1415-
Write("(", Translate(node.Type), ")");
1453+
if (!node.Type.IsAssignableFrom(node.Operand.Type))
1454+
Write("(", Translate(node.Type), ")");
14161455
break;
14171456

14181457
case ExpressionType.Throw:

0 commit comments

Comments
 (0)