public override Expression VisitExpression(Expression expression) { if (expression == null) return null; switch (expression.NodeType) { case NodeType.Dup: case NodeType.Arglist: expression = (Expression)expression.Clone(); break; case NodeType.Pop: UnaryExpression uex = expression as UnaryExpression; if (uex != null) { uex = (UnaryExpression)uex.Clone(); uex.Operand = this.VisitExpression(uex.Operand); expression = uex; } else expression = (Expression)expression.Clone(); break; default: expression = (Expression)this.Visit(expression); break; } if (expression == null) return null; expression.Type = this.VisitTypeReference(expression.Type); return expression; }
private Expression Visit(Expression expression) { Contract.Requires(this.Depth >= 0); Contract.Ensures(this.Depth >= 0); if (this.introducedClosureLocal == null) return expression; if (expression == null) return null; switch (expression.NodeType) { case NodeType.MemberBinding: var mb = (MemberBinding) expression.Clone(); mb.TargetObject = Visit(mb.TargetObject); return mb; case NodeType.This: case NodeType.Parameter: case NodeType.Local: break; case NodeType.Pop: if (this.Depth == 0) { return this.introducedClosureLocal; } this.Depth--; break; case NodeType.Literal: case NodeType.Arglist: break; case NodeType.AddressDereference: var ad = (AddressDereference) expression.Clone(); ad.Address = Visit(ad.Address); return ad; case NodeType.Construct: var c = (Construct) expression.Clone(); c.Operands = Visit(c.Operands); return c; case NodeType.ConstructArray: var ca = (ConstructArray) expression.Clone(); ca.Operands = Visit(ca.Operands); return ca; case NodeType.Call: case NodeType.Callvirt: var call = (MethodCall) expression.Clone(); call.Callee = Visit(call.Callee); call.Operands = Visit(call.Operands); return call; case NodeType.Cpblk: case NodeType.Initblk: var tern = (TernaryExpression) expression.Clone(); tern.Operand1 = Visit(tern.Operand1); tern.Operand2 = Visit(tern.Operand2); tern.Operand3 = Visit(tern.Operand3); return tern; case NodeType.Indexer: var indexer = (Indexer) expression.Clone(); indexer.Object = Visit(indexer.Object); indexer.Operands = Visit(indexer.Operands); return indexer; default: var binary = expression as BinaryExpression; if (binary != null) { binary = (BinaryExpression) binary.Clone(); binary.Operand1 = Visit(binary.Operand1); binary.Operand2 = Visit(binary.Operand2); return binary; } var unary = expression as UnaryExpression; if (unary != null) { unary = (UnaryExpression) unary.Clone(); unary.Operand = Visit(unary.Operand); return unary; } throw new NotImplementedException("ClosureNormalization Expression"); } return expression; }
/// <summary> /// /// </summary> private Expression simplify_addressof_operand(Expression operand) { switch(operand.NodeType) { case NodeType.This: case NodeType.Parameter: case NodeType.Local: // 1. & variable; ParameterBinding pb = operand as ParameterBinding; if (pb != null) { This tp = pb.BoundParameter as This; if (tp != null) { operand = pb = (ParameterBinding)pb.Clone(); pb.BoundParameter = (Parameter)this.VisitThis(tp); } } break; case NodeType.Indexer: // 2. & array[index] operand = (Expression)operand.Clone(); Indexer indexer = (Indexer) operand; indexer.Object = simplify(indexer.Object); ExpressionList ops = VisitExpressionList(indexer.Operands); System.Diagnostics.Debug.Assert(ops != null, "VisitExpressionList must return non-null if arg non-null"); indexer.Operands = ops; break; case NodeType.MemberBinding: // 3. & object.field operand = (Expression)operand.Clone(); MemberBinding mb = (MemberBinding) operand; if (mb.TargetObject != null) { mb.TargetObject = simplify(mb.TargetObject); } break; default: throw new ApplicationException("Strange AddressOf expression: "); } return operand; }