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
- CompressionTransform.cs
- Delay.cs
- CodeStatementCollection.cs
- DataSourceListEditor.cs
- CombinedGeometry.cs
- Camera.cs
- linebase.cs
- DbConnectionPoolOptions.cs
- GenericXmlSecurityToken.cs
- ContextStaticAttribute.cs
- GenericArgumentsUpdater.cs
- OleDbRowUpdatingEvent.cs
- XsdCachingReader.cs
- PixelFormat.cs
- ResourceDescriptionAttribute.cs
- URLString.cs
- DictionarySurrogate.cs
- DSACryptoServiceProvider.cs
- TextRangeEdit.cs
- DataGridViewCellEventArgs.cs
- XmlSchemaSimpleContentExtension.cs
- TypeDescriptor.cs
- CmsInterop.cs
- TableRow.cs
- ClientScriptManager.cs
- SafeFindHandle.cs
- SafeNativeMethods.cs
- Attributes.cs
- CancellationToken.cs
- SynchronizingStream.cs
- Predicate.cs
- SchemaNamespaceManager.cs
- TextBoxBase.cs
- ConnectionInterfaceCollection.cs
- AlphaSortedEnumConverter.cs
- StrokeSerializer.cs
- SynchronizationScope.cs
- CharEnumerator.cs
- Color.cs
- PeerTransportListenAddressConverter.cs
- NumericUpDownAcceleration.cs
- DataContractSet.cs
- SqlTrackingWorkflowInstance.cs
- HtmlControl.cs
- ButtonChrome.cs
- ToolStripStatusLabel.cs
- ConstantSlot.cs
- Style.cs
- Activator.cs
- DataMemberFieldEditor.cs
- WebScriptEnablingElement.cs
- UnsafeNativeMethodsTablet.cs
- DesignBindingValueUIHandler.cs
- LookupBindingPropertiesAttribute.cs
- ComponentTray.cs
- VisualBasicDesignerHelper.cs
- ScalarConstant.cs
- SourceSwitch.cs
- SchemaTableColumn.cs
- XmlDataDocument.cs
- CachedTypeface.cs
- WindowsIdentity.cs
- AttachedPropertyMethodSelector.cs
- SourceSwitch.cs
- KeyFrames.cs
- RuleSettingsCollection.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- XmlArrayAttribute.cs
- FastPropertyAccessor.cs
- RolePrincipal.cs
- Crc32.cs
- EditBehavior.cs
- XslTransform.cs
- BitmapCacheBrush.cs
- SettingsSavedEventArgs.cs
- OdbcStatementHandle.cs
- AddressingProperty.cs
- precedingquery.cs
- Variable.cs
- TlsnegoTokenAuthenticator.cs
- Control.cs
- HttpRequestCacheValidator.cs
- SafeNativeHandle.cs
- Pair.cs
- PropertyValueChangedEvent.cs
- AttributeSetAction.cs
- MembershipPasswordException.cs
- ListenerBinder.cs
- ClientConfigPaths.cs
- MappedMetaModel.cs
- AppearanceEditorPart.cs
- TextCompositionEventArgs.cs
- XmlSchemaSimpleContentExtension.cs
- Subset.cs
- ColumnReorderedEventArgs.cs
- SafeHandles.cs
- SystemDiagnosticsSection.cs
- WebPartEditorOkVerb.cs
- StrongNameUtility.cs
- SystemFonts.cs