Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ALinq / ALinqExpressionVisitor.cs / 1305376 / ALinqExpressionVisitor.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// Expression Visitor // // // @owner [....] //--------------------------------------------------------------------- #if ASTORIA_SERVER namespace System.Data.Services #else namespace System.Data.Services.Client #endif { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq.Expressions; #if ASTORIA_LIGHT using System.Reflection; using System.Security; using System.Security.Permissions; ////// This class introduced because of a bug in SL3 which prevents using non-public (e.g anonymous) types as return types for lambdas /// We should be able to remove this for SL4. /// internal static class ExpressionHelpers { private static MethodInfo lambdaFunc; internal static LambdaExpression CreateLambda(Expression body, params ParameterExpression[] parameters) { return CreateLambda(InferDelegateType(body, parameters), body, parameters); } // This creates a tree and compiles it just for the purposes of creating the real lambda internal static LambdaExpression CreateLambda(Type delegateType, Expression body, params ParameterExpression[] parameters) { // Expression.Lambda() doesn't work directly if "body" is a non-public type // Work around this by calling the factory from a DynamicMethod. var args = new[] { Expression.Parameter(typeof(Expression), "body"), Expression.Parameter(typeof(ParameterExpression[]), "parameters") }; var lambdaFactory = Expression.Lambda>( Expression.Call(GetLambdaFactoryMethod(delegateType), args), args ); return lambdaFactory.Compile().Invoke(body, parameters); } private static Type InferDelegateType(Expression body, params ParameterExpression[] parameters) { bool isVoid = body.Type == typeof(void); int length = (parameters == null) ? 0 : parameters.Length; var typeArgs = new Type[length + (isVoid ? 0 : 1)]; for (int i = 0; i < length; i++) { typeArgs[i] = parameters[i].Type; } if (isVoid) { return Expression.GetActionType(typeArgs); } else { typeArgs[length] = body.Type; return Expression.GetFuncType(typeArgs); } } private static MethodInfo GetLambdaFactoryMethod(Type delegateType) { // Gets the MethodInfo for Expression.Lambda (Expression body, params ParameterExpression[] parameters) if (lambdaFunc == null) { lambdaFunc = new Func >(Expression.Lambda ).Method.GetGenericMethodDefinition(); } //Create a throwaway delegate to bind to the right Labda function with a specific delegate type. return lambdaFunc.MakeGenericMethod(delegateType); } } #endif /// /// base vistor class for walking an expression tree bottom up. /// internal abstract class ALinqExpressionVisitor { ////// Main visit method for ALinqExpressionVisitor /// /// The expression to visit ///The visited expression internal virtual Expression Visit(Expression exp) { if (exp == null) { return exp; } switch (exp.NodeType) { case ExpressionType.UnaryPlus: case ExpressionType.Negate: case ExpressionType.NegateChecked: case ExpressionType.Not: case ExpressionType.Convert: case ExpressionType.ConvertChecked: case ExpressionType.ArrayLength: case ExpressionType.Quote: case ExpressionType.TypeAs: return this.VisitUnary((UnaryExpression)exp); case ExpressionType.Add: case ExpressionType.AddChecked: case ExpressionType.Subtract: case ExpressionType.SubtractChecked: case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: case ExpressionType.Divide: case ExpressionType.Modulo: #if !ASTORIA_CLIENT case ExpressionType.Power: #endif case ExpressionType.And: case ExpressionType.AndAlso: case ExpressionType.Or: case ExpressionType.OrElse: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.Equal: case ExpressionType.NotEqual: case ExpressionType.Coalesce: case ExpressionType.ArrayIndex: case ExpressionType.RightShift: case ExpressionType.LeftShift: case ExpressionType.ExclusiveOr: return this.VisitBinary((BinaryExpression)exp); case ExpressionType.TypeIs: return this.VisitTypeIs((TypeBinaryExpression)exp); case ExpressionType.Conditional: return this.VisitConditional((ConditionalExpression)exp); case ExpressionType.Constant: return this.VisitConstant((ConstantExpression)exp); case ExpressionType.Parameter: return this.VisitParameter((ParameterExpression)exp); case ExpressionType.MemberAccess: return this.VisitMemberAccess((MemberExpression)exp); case ExpressionType.Call: return this.VisitMethodCall((MethodCallExpression)exp); case ExpressionType.Lambda: return this.VisitLambda((LambdaExpression)exp); case ExpressionType.New: return this.VisitNew((NewExpression)exp); case ExpressionType.NewArrayInit: case ExpressionType.NewArrayBounds: return this.VisitNewArray((NewArrayExpression)exp); case ExpressionType.Invoke: return this.VisitInvocation((InvocationExpression)exp); case ExpressionType.MemberInit: return this.VisitMemberInit((MemberInitExpression)exp); case ExpressionType.ListInit: return this.VisitListInit((ListInitExpression)exp); default: throw new NotSupportedException(Strings.ALinq_UnsupportedExpression(exp.NodeType.ToString())); } } ////// MemberBinding visit method /// /// The MemberBinding expression to visit ///The visited MemberBinding expression internal virtual MemberBinding VisitBinding(MemberBinding binding) { switch (binding.BindingType) { case MemberBindingType.Assignment: return this.VisitMemberAssignment((MemberAssignment)binding); case MemberBindingType.MemberBinding: return this.VisitMemberMemberBinding((MemberMemberBinding)binding); case MemberBindingType.ListBinding: return this.VisitMemberListBinding((MemberListBinding)binding); default: throw new NotSupportedException(Strings.ALinq_UnsupportedExpression(binding.BindingType.ToString())); } } ////// ElementInit visit method /// /// The ElementInit expression to visit ///The visited ElementInit expression internal virtual ElementInit VisitElementInitializer(ElementInit initializer) { ReadOnlyCollectionarguments = this.VisitExpressionList(initializer.Arguments); if (arguments != initializer.Arguments) { return Expression.ElementInit(initializer.AddMethod, arguments); } return initializer; } /// /// UnaryExpression visit method /// /// The UnaryExpression expression to visit ///The visited UnaryExpression expression internal virtual Expression VisitUnary(UnaryExpression u) { Expression operand = this.Visit(u.Operand); if (operand != u.Operand) { return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method); } return u; } ////// BinaryExpression visit method /// /// The BinaryExpression expression to visit ///The visited BinaryExpression expression internal virtual Expression VisitBinary(BinaryExpression b) { Expression left = this.Visit(b.Left); Expression right = this.Visit(b.Right); Expression conversion = this.Visit(b.Conversion); if (left != b.Left || right != b.Right || conversion != b.Conversion) { if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null) { return Expression.Coalesce(left, right, conversion as LambdaExpression); } else { return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method); } } return b; } ////// TypeBinaryExpression visit method /// /// The TypeBinaryExpression expression to visit ///The visited TypeBinaryExpression expression internal virtual Expression VisitTypeIs(TypeBinaryExpression b) { Expression expr = this.Visit(b.Expression); if (expr != b.Expression) { return Expression.TypeIs(expr, b.TypeOperand); } return b; } ////// ConstantExpression visit method /// /// The ConstantExpression expression to visit ///The visited ConstantExpression expression internal virtual Expression VisitConstant(ConstantExpression c) { return c; } ////// ConditionalExpression visit method /// /// The ConditionalExpression expression to visit ///The visited ConditionalExpression expression internal virtual Expression VisitConditional(ConditionalExpression c) { Expression test = this.Visit(c.Test); Expression iftrue = this.Visit(c.IfTrue); Expression iffalse = this.Visit(c.IfFalse); if (test != c.Test || iftrue != c.IfTrue || iffalse != c.IfFalse) { return Expression.Condition(test, iftrue, iffalse); } return c; } ////// ParameterExpression visit method /// /// The ParameterExpression expression to visit ///The visited ParameterExpression expression internal virtual Expression VisitParameter(ParameterExpression p) { return p; } ////// MemberExpression visit method /// /// The MemberExpression expression to visit ///The visited MemberExpression expression internal virtual Expression VisitMemberAccess(MemberExpression m) { Expression exp = this.Visit(m.Expression); if (exp != m.Expression) { return Expression.MakeMemberAccess(exp, m.Member); } return m; } ////// MethodCallExpression visit method /// /// The MethodCallExpression expression to visit ///The visited MethodCallExpression expression internal virtual Expression VisitMethodCall(MethodCallExpression m) { Expression obj = this.Visit(m.Object); IEnumerableargs = this.VisitExpressionList(m.Arguments); if (obj != m.Object || args != m.Arguments) { return Expression.Call(obj, m.Method, args); } return m; } /// /// Expression list visit method /// /// The expression list to visit ///The visited expression list internal virtual ReadOnlyCollectionVisitExpressionList(ReadOnlyCollection original) { List list = null; for (int i = 0, n = original.Count; i < n; i++) { Expression p = this.Visit(original[i]); if (list != null) { list.Add(p); } else if (p != original[i]) { list = new List (n); for (int j = 0; j < i; j++) { list.Add(original[j]); } list.Add(p); } } if (list != null) { return new ReadOnlyCollection (list); } return original; } /// /// MemberAssignment visit method /// /// The MemberAssignment to visit ///The visited MemberAssignmentt internal virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment) { Expression e = this.Visit(assignment.Expression); if (e != assignment.Expression) { return Expression.Bind(assignment.Member, e); } return assignment; } ////// MemberMemberBinding visit method /// /// The MemberMemberBinding to visit ///The visited MemberMemberBinding internal virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding) { IEnumerablebindings = this.VisitBindingList(binding.Bindings); if (bindings != binding.Bindings) { return Expression.MemberBind(binding.Member, bindings); } return binding; } /// /// MemberListBinding visit method /// /// The MemberListBinding to visit ///The visited MemberListBinding internal virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding) { IEnumerableinitializers = this.VisitElementInitializerList(binding.Initializers); if (initializers != binding.Initializers) { return Expression.ListBind(binding.Member, initializers); } return binding; } /// /// Binding List visit method /// /// The Binding list to visit ///The visited Binding list internal virtual IEnumerableVisitBindingList(ReadOnlyCollection original) { List list = null; for (int i = 0, n = original.Count; i < n; i++) { MemberBinding b = this.VisitBinding(original[i]); if (list != null) { list.Add(b); } else if (b != original[i]) { list = new List (n); for (int j = 0; j < i; j++) { list.Add(original[j]); } list.Add(b); } } if (list != null) { return list; } return original; } /// /// ElementInit expression list visit method /// /// The ElementInit expression list to visit ///The visited ElementInit expression list internal virtual IEnumerableVisitElementInitializerList(ReadOnlyCollection original) { List list = null; for (int i = 0, n = original.Count; i < n; i++) { ElementInit init = this.VisitElementInitializer(original[i]); if (list != null) { list.Add(init); } else if (init != original[i]) { list = new List (n); for (int j = 0; j < i; j++) { list.Add(original[j]); } list.Add(init); } } if (list != null) { return list; } return original; } /// /// LambdaExpression visit method /// /// The LambdaExpression to visit ///The visited LambdaExpression internal virtual Expression VisitLambda(LambdaExpression lambda) { Expression body = this.Visit(lambda.Body); if (body != lambda.Body) { #if !ASTORIA_LIGHT return Expression.Lambda(lambda.Type, body, lambda.Parameters); #else ParameterExpression[] parameters = new ParameterExpression[lambda.Parameters.Count]; lambda.Parameters.CopyTo(parameters, 0); return ExpressionHelpers.CreateLambda(lambda.Type, body, parameters); #endif } return lambda; } ////// NewExpression visit method /// /// The NewExpression to visit ///The visited NewExpression internal virtual NewExpression VisitNew(NewExpression nex) { IEnumerableargs = this.VisitExpressionList(nex.Arguments); if (args != nex.Arguments) { if (nex.Members != null) { return Expression.New(nex.Constructor, args, nex.Members); } else { return Expression.New(nex.Constructor, args); } } return nex; } /// /// MemberInitExpression visit method /// /// The MemberInitExpression to visit ///The visited MemberInitExpression internal virtual Expression VisitMemberInit(MemberInitExpression init) { NewExpression n = this.VisitNew(init.NewExpression); IEnumerablebindings = this.VisitBindingList(init.Bindings); if (n != init.NewExpression || bindings != init.Bindings) { return Expression.MemberInit(n, bindings); } return init; } /// /// ListInitExpression visit method /// /// The ListInitExpression to visit ///The visited ListInitExpression internal virtual Expression VisitListInit(ListInitExpression init) { NewExpression n = this.VisitNew(init.NewExpression); IEnumerableinitializers = this.VisitElementInitializerList(init.Initializers); if (n != init.NewExpression || initializers != init.Initializers) { return Expression.ListInit(n, initializers); } return init; } /// /// NewArrayExpression visit method /// /// The NewArrayExpression to visit ///The visited NewArrayExpression internal virtual Expression VisitNewArray(NewArrayExpression na) { IEnumerableexprs = this.VisitExpressionList(na.Expressions); if (exprs != na.Expressions) { if (na.NodeType == ExpressionType.NewArrayInit) { return Expression.NewArrayInit(na.Type.GetElementType(), exprs); } else { return Expression.NewArrayBounds(na.Type.GetElementType(), exprs); } } return na; } /// /// InvocationExpression visit method /// /// The InvocationExpression to visit ///The visited InvocationExpression internal virtual Expression VisitInvocation(InvocationExpression iv) { IEnumerableargs = this.VisitExpressionList(iv.Arguments); Expression expr = this.Visit(iv.Expression); if (args != iv.Arguments || expr != iv.Expression) { return Expression.Invoke(expr, args); } return iv; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IndividualDeviceConfig.cs
- PageThemeCodeDomTreeGenerator.cs
- TypeFieldSchema.cs
- WindowsGrip.cs
- httpapplicationstate.cs
- XmlSchemaImporter.cs
- XamlVector3DCollectionSerializer.cs
- PolicyLevel.cs
- PresentationAppDomainManager.cs
- ParameterBuilder.cs
- CharacterBuffer.cs
- DecimalAnimation.cs
- MeshGeometry3D.cs
- EntryPointNotFoundException.cs
- CallbackException.cs
- SafeEventLogReadHandle.cs
- TemplateInstanceAttribute.cs
- MessageSmuggler.cs
- LinearGradientBrush.cs
- TreeViewDesigner.cs
- ReliableOutputSessionChannel.cs
- RequestCachingSection.cs
- DataControlImageButton.cs
- EventWaitHandleSecurity.cs
- RowType.cs
- SourceItem.cs
- IndexerReference.cs
- TextRunProperties.cs
- PeerCustomResolverElement.cs
- SqlEnums.cs
- MethodCallTranslator.cs
- FontStyleConverter.cs
- ToolStripButton.cs
- LineUtil.cs
- StringArrayConverter.cs
- NoResizeHandleGlyph.cs
- ComplexLine.cs
- DataGridColumnCollection.cs
- ThicknessConverter.cs
- DataMemberAttribute.cs
- OdbcHandle.cs
- DataGridViewRowEventArgs.cs
- MergePropertyDescriptor.cs
- SmiMetaDataProperty.cs
- MetadataItemCollectionFactory.cs
- SqlWebEventProvider.cs
- SourceItem.cs
- SoapReflectionImporter.cs
- ToolboxItemFilterAttribute.cs
- ByteAnimation.cs
- ScrollBar.cs
- SqlServer2KCompatibilityCheck.cs
- SHA512.cs
- LinqDataSourceSelectEventArgs.cs
- GatewayDefinition.cs
- XmlAttributeCache.cs
- FixedPage.cs
- Message.cs
- WebPageTraceListener.cs
- SqlDataSourceCache.cs
- XPathNodeInfoAtom.cs
- XmlNamespaceManager.cs
- WpfSharedXamlSchemaContext.cs
- OutputCacheSection.cs
- SchemaObjectWriter.cs
- DatatypeImplementation.cs
- ListBoxAutomationPeer.cs
- StrokeCollection.cs
- DragSelectionMessageFilter.cs
- ImageList.cs
- Point3DAnimationBase.cs
- XmlCharCheckingReader.cs
- Int16Storage.cs
- RawStylusInput.cs
- DataList.cs
- OdbcConnectionString.cs
- MatrixTransform.cs
- ObjectResult.cs
- FlagsAttribute.cs
- XamlRtfConverter.cs
- Utils.cs
- PathFigure.cs
- DataRowChangeEvent.cs
- HighlightComponent.cs
- MouseCaptureWithinProperty.cs
- ComEventsMethod.cs
- SafeNativeMethods.cs
- EntityDataSourceChangingEventArgs.cs
- Rect3D.cs
- TreeNodeCollection.cs
- GeometryCombineModeValidation.cs
- MonthChangedEventArgs.cs
- SynchronizingStream.cs
- ZipIOExtraFieldZip64Element.cs
- XmlSerializationWriter.cs
- XmlSchema.cs
- SafeSecurityHelper.cs
- HtmlListAdapter.cs
- ErrorRuntimeConfig.cs
- SimpleNameService.cs