425 lines
12 KiB
C#
425 lines
12 KiB
C#
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Text;
|
|
|
|
namespace System.Linq.Expressions
|
|
{
|
|
// Token: 0x0200001D RID: 29
|
|
internal class ExpressionPrinter : ExpressionVisitor
|
|
{
|
|
// Token: 0x060001AC RID: 428 RVA: 0x00009E64 File Offset: 0x00008064
|
|
private ExpressionPrinter(StringBuilder builder)
|
|
{
|
|
this.builder = builder;
|
|
}
|
|
|
|
// Token: 0x060001AD RID: 429 RVA: 0x00009E74 File Offset: 0x00008074
|
|
private ExpressionPrinter()
|
|
: this(new StringBuilder())
|
|
{
|
|
}
|
|
|
|
// Token: 0x060001AE RID: 430 RVA: 0x00009E84 File Offset: 0x00008084
|
|
public static string ToString(Expression expression)
|
|
{
|
|
ExpressionPrinter expressionPrinter = new ExpressionPrinter();
|
|
expressionPrinter.Visit(expression);
|
|
return expressionPrinter.builder.ToString();
|
|
}
|
|
|
|
// Token: 0x060001AF RID: 431 RVA: 0x00009EAC File Offset: 0x000080AC
|
|
public static string ToString(ElementInit init)
|
|
{
|
|
ExpressionPrinter expressionPrinter = new ExpressionPrinter();
|
|
expressionPrinter.VisitElementInitializer(init);
|
|
return expressionPrinter.builder.ToString();
|
|
}
|
|
|
|
// Token: 0x060001B0 RID: 432 RVA: 0x00009ED4 File Offset: 0x000080D4
|
|
public static string ToString(MemberBinding binding)
|
|
{
|
|
ExpressionPrinter expressionPrinter = new ExpressionPrinter();
|
|
expressionPrinter.VisitBinding(binding);
|
|
return expressionPrinter.builder.ToString();
|
|
}
|
|
|
|
// Token: 0x060001B1 RID: 433 RVA: 0x00009EFC File Offset: 0x000080FC
|
|
private void Print(string str)
|
|
{
|
|
this.builder.Append(str);
|
|
}
|
|
|
|
// Token: 0x060001B2 RID: 434 RVA: 0x00009F0C File Offset: 0x0000810C
|
|
private void Print(object obj)
|
|
{
|
|
this.builder.Append(obj);
|
|
}
|
|
|
|
// Token: 0x060001B3 RID: 435 RVA: 0x00009F1C File Offset: 0x0000811C
|
|
private void Print(string str, params object[] objs)
|
|
{
|
|
this.builder.AppendFormat(str, objs);
|
|
}
|
|
|
|
// Token: 0x060001B4 RID: 436 RVA: 0x00009F2C File Offset: 0x0000812C
|
|
protected override void VisitElementInitializer(ElementInit initializer)
|
|
{
|
|
this.Print(initializer.AddMethod);
|
|
this.Print("(");
|
|
this.VisitExpressionList(initializer.Arguments);
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x060001B5 RID: 437 RVA: 0x00009F68 File Offset: 0x00008168
|
|
protected override void VisitUnary(UnaryExpression unary)
|
|
{
|
|
ExpressionType nodeType = unary.NodeType;
|
|
if (nodeType != ExpressionType.Convert && nodeType != ExpressionType.ConvertChecked)
|
|
{
|
|
if (nodeType == ExpressionType.Negate)
|
|
{
|
|
this.Print("-");
|
|
this.Visit(unary.Operand);
|
|
return;
|
|
}
|
|
if (nodeType == ExpressionType.UnaryPlus)
|
|
{
|
|
this.Print("+");
|
|
this.Visit(unary.Operand);
|
|
return;
|
|
}
|
|
if (nodeType != ExpressionType.ArrayLength && nodeType != ExpressionType.Not)
|
|
{
|
|
if (nodeType == ExpressionType.Quote)
|
|
{
|
|
this.Visit(unary.Operand);
|
|
return;
|
|
}
|
|
if (nodeType != ExpressionType.TypeAs)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
this.Print("(");
|
|
this.Visit(unary.Operand);
|
|
this.Print(" As {0})", new object[] { unary.Type.Name });
|
|
return;
|
|
}
|
|
}
|
|
this.Print("{0}(", new object[] { unary.NodeType });
|
|
this.Visit(unary.Operand);
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x060001B6 RID: 438 RVA: 0x0000A070 File Offset: 0x00008270
|
|
private static string OperatorToString(BinaryExpression binary)
|
|
{
|
|
switch (binary.NodeType)
|
|
{
|
|
case ExpressionType.Add:
|
|
case ExpressionType.AddChecked:
|
|
return "+";
|
|
case ExpressionType.And:
|
|
return (!ExpressionPrinter.IsBoolean(binary)) ? "&" : "And";
|
|
case ExpressionType.AndAlso:
|
|
return "&&";
|
|
case ExpressionType.Coalesce:
|
|
return "??";
|
|
case ExpressionType.Divide:
|
|
return "/";
|
|
case ExpressionType.Equal:
|
|
return "=";
|
|
case ExpressionType.ExclusiveOr:
|
|
return "^";
|
|
case ExpressionType.GreaterThan:
|
|
return ">";
|
|
case ExpressionType.GreaterThanOrEqual:
|
|
return ">=";
|
|
case ExpressionType.LeftShift:
|
|
return "<<";
|
|
case ExpressionType.LessThan:
|
|
return "<";
|
|
case ExpressionType.LessThanOrEqual:
|
|
return "<=";
|
|
case ExpressionType.Modulo:
|
|
return "%";
|
|
case ExpressionType.Multiply:
|
|
case ExpressionType.MultiplyChecked:
|
|
return "*";
|
|
case ExpressionType.NotEqual:
|
|
return "!=";
|
|
case ExpressionType.Or:
|
|
return (!ExpressionPrinter.IsBoolean(binary)) ? "|" : "Or";
|
|
case ExpressionType.OrElse:
|
|
return "||";
|
|
case ExpressionType.Power:
|
|
return "^";
|
|
case ExpressionType.RightShift:
|
|
return ">>";
|
|
case ExpressionType.Subtract:
|
|
case ExpressionType.SubtractChecked:
|
|
return "-";
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x060001B7 RID: 439 RVA: 0x0000A1E4 File Offset: 0x000083E4
|
|
private static bool IsBoolean(Expression expression)
|
|
{
|
|
return expression.Type == typeof(bool) || expression.Type == typeof(bool?);
|
|
}
|
|
|
|
// Token: 0x060001B8 RID: 440 RVA: 0x0000A21C File Offset: 0x0000841C
|
|
private void PrintArrayIndex(BinaryExpression index)
|
|
{
|
|
this.Visit(index.Left);
|
|
this.Print("[");
|
|
this.Visit(index.Right);
|
|
this.Print("]");
|
|
}
|
|
|
|
// Token: 0x060001B9 RID: 441 RVA: 0x0000A258 File Offset: 0x00008458
|
|
protected override void VisitBinary(BinaryExpression binary)
|
|
{
|
|
ExpressionType nodeType = binary.NodeType;
|
|
if (nodeType != ExpressionType.ArrayIndex)
|
|
{
|
|
this.Print("(");
|
|
this.Visit(binary.Left);
|
|
this.Print(" {0} ", new object[] { ExpressionPrinter.OperatorToString(binary) });
|
|
this.Visit(binary.Right);
|
|
this.Print(")");
|
|
return;
|
|
}
|
|
this.PrintArrayIndex(binary);
|
|
}
|
|
|
|
// Token: 0x060001BA RID: 442 RVA: 0x0000A2C8 File Offset: 0x000084C8
|
|
protected override void VisitTypeIs(TypeBinaryExpression type)
|
|
{
|
|
ExpressionType nodeType = type.NodeType;
|
|
if (nodeType != ExpressionType.TypeIs)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
this.Print("(");
|
|
this.Visit(type.Expression);
|
|
this.Print(" Is {0})", new object[] { type.TypeOperand.Name });
|
|
}
|
|
|
|
// Token: 0x060001BB RID: 443 RVA: 0x0000A328 File Offset: 0x00008528
|
|
protected override void VisitConstant(ConstantExpression constant)
|
|
{
|
|
object value = constant.Value;
|
|
if (value == null)
|
|
{
|
|
this.Print("null");
|
|
}
|
|
else if (value is string)
|
|
{
|
|
this.Print("\"");
|
|
this.Print(value);
|
|
this.Print("\"");
|
|
}
|
|
else if (!ExpressionPrinter.HasStringRepresentation(value))
|
|
{
|
|
this.Print("value(");
|
|
this.Print(value);
|
|
this.Print(")");
|
|
}
|
|
else
|
|
{
|
|
this.Print(value);
|
|
}
|
|
}
|
|
|
|
// Token: 0x060001BC RID: 444 RVA: 0x0000A3B4 File Offset: 0x000085B4
|
|
private static bool HasStringRepresentation(object obj)
|
|
{
|
|
return obj.ToString() != obj.GetType().ToString();
|
|
}
|
|
|
|
// Token: 0x060001BD RID: 445 RVA: 0x0000A3D8 File Offset: 0x000085D8
|
|
protected override void VisitConditional(ConditionalExpression conditional)
|
|
{
|
|
this.Print("IIF(");
|
|
this.Visit(conditional.Test);
|
|
this.Print(", ");
|
|
this.Visit(conditional.IfTrue);
|
|
this.Print(", ");
|
|
this.Visit(conditional.IfFalse);
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x060001BE RID: 446 RVA: 0x0000A438 File Offset: 0x00008638
|
|
protected override void VisitParameter(ParameterExpression parameter)
|
|
{
|
|
this.Print(parameter.Name ?? "<param>");
|
|
}
|
|
|
|
// Token: 0x060001BF RID: 447 RVA: 0x0000A454 File Offset: 0x00008654
|
|
protected override void VisitMemberAccess(MemberExpression access)
|
|
{
|
|
if (access.Expression == null)
|
|
{
|
|
this.Print(access.Member.DeclaringType.Name);
|
|
}
|
|
else
|
|
{
|
|
this.Visit(access.Expression);
|
|
}
|
|
this.Print(".{0}", new object[] { access.Member.Name });
|
|
}
|
|
|
|
// Token: 0x060001C0 RID: 448 RVA: 0x0000A4B4 File Offset: 0x000086B4
|
|
protected override void VisitMethodCall(MethodCallExpression call)
|
|
{
|
|
if (call.Object != null)
|
|
{
|
|
this.Visit(call.Object);
|
|
this.Print(".");
|
|
}
|
|
this.Print(call.Method.Name);
|
|
this.Print("(");
|
|
this.VisitExpressionList(call.Arguments);
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x060001C1 RID: 449 RVA: 0x0000A518 File Offset: 0x00008718
|
|
protected override void VisitMemberAssignment(MemberAssignment assignment)
|
|
{
|
|
this.Print("{0} = ", new object[] { assignment.Member.Name });
|
|
this.Visit(assignment.Expression);
|
|
}
|
|
|
|
// Token: 0x060001C2 RID: 450 RVA: 0x0000A550 File Offset: 0x00008750
|
|
protected override void VisitMemberMemberBinding(MemberMemberBinding binding)
|
|
{
|
|
this.Print(binding.Member.Name);
|
|
this.Print(" = {");
|
|
this.VisitList<MemberBinding>(binding.Bindings, new Action<MemberBinding>(this.VisitBinding));
|
|
this.Print("}");
|
|
}
|
|
|
|
// Token: 0x060001C3 RID: 451 RVA: 0x0000A5A0 File Offset: 0x000087A0
|
|
protected override void VisitMemberListBinding(MemberListBinding binding)
|
|
{
|
|
this.Print(binding.Member.Name);
|
|
this.Print(" = {");
|
|
this.VisitList<ElementInit>(binding.Initializers, new Action<ElementInit>(this.VisitElementInitializer));
|
|
this.Print("}");
|
|
}
|
|
|
|
// Token: 0x060001C4 RID: 452 RVA: 0x0000A5F0 File Offset: 0x000087F0
|
|
protected override void VisitList<T>(ReadOnlyCollection<T> list, Action<T> visitor)
|
|
{
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
this.Print(", ");
|
|
}
|
|
visitor(list[i]);
|
|
}
|
|
}
|
|
|
|
// Token: 0x060001C5 RID: 453 RVA: 0x0000A634 File Offset: 0x00008834
|
|
protected override void VisitLambda(LambdaExpression lambda)
|
|
{
|
|
if (lambda.Parameters.Count != 1)
|
|
{
|
|
this.Print("(");
|
|
this.VisitList<ParameterExpression>(lambda.Parameters, new Action<ParameterExpression>(this.Visit));
|
|
this.Print(")");
|
|
}
|
|
else
|
|
{
|
|
this.Visit(lambda.Parameters[0]);
|
|
}
|
|
this.Print(" => ");
|
|
this.Visit(lambda.Body);
|
|
}
|
|
|
|
// Token: 0x060001C6 RID: 454 RVA: 0x0000A6B0 File Offset: 0x000088B0
|
|
protected override void VisitNew(NewExpression nex)
|
|
{
|
|
this.Print("new {0}(", new object[] { nex.Type.Name });
|
|
if (nex.Members != null && nex.Members.Count > 0)
|
|
{
|
|
for (int i = 0; i < nex.Members.Count; i++)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
this.Print(", ");
|
|
}
|
|
this.Print("{0} = ", new object[] { nex.Members[i].Name });
|
|
this.Visit(nex.Arguments[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.VisitExpressionList(nex.Arguments);
|
|
}
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x060001C7 RID: 455 RVA: 0x0000A77C File Offset: 0x0000897C
|
|
protected override void VisitMemberInit(MemberInitExpression init)
|
|
{
|
|
this.Visit(init.NewExpression);
|
|
this.Print(" {");
|
|
this.VisitList<MemberBinding>(init.Bindings, new Action<MemberBinding>(this.VisitBinding));
|
|
this.Print("}");
|
|
}
|
|
|
|
// Token: 0x060001C8 RID: 456 RVA: 0x0000A7C4 File Offset: 0x000089C4
|
|
protected override void VisitListInit(ListInitExpression init)
|
|
{
|
|
this.Visit(init.NewExpression);
|
|
this.Print(" {");
|
|
this.VisitList<ElementInit>(init.Initializers, new Action<ElementInit>(this.VisitElementInitializer));
|
|
this.Print("}");
|
|
}
|
|
|
|
// Token: 0x060001C9 RID: 457 RVA: 0x0000A80C File Offset: 0x00008A0C
|
|
protected override void VisitNewArray(NewArrayExpression newArray)
|
|
{
|
|
this.Print("new ");
|
|
ExpressionType nodeType = newArray.NodeType;
|
|
if (nodeType == ExpressionType.NewArrayInit)
|
|
{
|
|
this.Print("[] {");
|
|
this.VisitExpressionList(newArray.Expressions);
|
|
this.Print("}");
|
|
return;
|
|
}
|
|
if (nodeType != ExpressionType.NewArrayBounds)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
this.Print(newArray.Type);
|
|
this.Print("(");
|
|
this.VisitExpressionList(newArray.Expressions);
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x060001CA RID: 458 RVA: 0x0000A898 File Offset: 0x00008A98
|
|
protected override void VisitInvocation(InvocationExpression invocation)
|
|
{
|
|
this.Print("Invoke(");
|
|
this.Visit(invocation.Expression);
|
|
if (invocation.Arguments.Count != 0)
|
|
{
|
|
this.Print(", ");
|
|
this.VisitExpressionList(invocation.Arguments);
|
|
}
|
|
this.Print(")");
|
|
}
|
|
|
|
// Token: 0x04000074 RID: 116
|
|
private const string ListSeparator = ", ";
|
|
|
|
// Token: 0x04000075 RID: 117
|
|
private StringBuilder builder;
|
|
}
|
|
}
|