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
- AudioDeviceOut.cs
- ColumnHeaderConverter.cs
- LocalizationCodeDomSerializer.cs
- EncoderParameters.cs
- mansign.cs
- HttpResponse.cs
- ToolStripContentPanelDesigner.cs
- MemoryMappedViewAccessor.cs
- ControlCachePolicy.cs
- DataGridViewRowPrePaintEventArgs.cs
- NameNode.cs
- DataGridRowHeader.cs
- XPathNode.cs
- __ConsoleStream.cs
- FontStretches.cs
- SiteOfOriginContainer.cs
- WeakReferenceList.cs
- ZipIOExtraFieldPaddingElement.cs
- AssertSection.cs
- SourceSwitch.cs
- Light.cs
- NavigationProperty.cs
- DynamicPropertyReader.cs
- XmlSchemaAttributeGroupRef.cs
- TextCollapsingProperties.cs
- CommandConverter.cs
- AppDomainShutdownMonitor.cs
- ProgressBar.cs
- ApplicationFileCodeDomTreeGenerator.cs
- ValidationEventArgs.cs
- ProviderUtil.cs
- CodeDirectoryCompiler.cs
- WebPartConnectionsEventArgs.cs
- WindowsStatic.cs
- Keywords.cs
- MergeLocalizationDirectives.cs
- MailDefinition.cs
- ConfigurationValidatorAttribute.cs
- ServiceDescriptionSerializer.cs
- CharEntityEncoderFallback.cs
- SingletonInstanceContextProvider.cs
- DataSetFieldSchema.cs
- ListBindingConverter.cs
- ADConnectionHelper.cs
- DetailsViewDeleteEventArgs.cs
- InputScopeConverter.cs
- ColumnBinding.cs
- PointCollection.cs
- ConfigurationValidatorAttribute.cs
- X509DefaultServiceCertificateElement.cs
- ClientConfigurationSystem.cs
- QuotaExceededException.cs
- ImportCatalogPart.cs
- JoinTreeSlot.cs
- UserControlBuildProvider.cs
- SignedXml.cs
- AppSettingsReader.cs
- WebCategoryAttribute.cs
- ArrayListCollectionBase.cs
- SerializationEventsCache.cs
- WebBrowserEvent.cs
- SingleTagSectionHandler.cs
- ModelPerspective.cs
- LocalFileSettingsProvider.cs
- Lease.cs
- SoapElementAttribute.cs
- DataErrorValidationRule.cs
- BypassElement.cs
- AssemblyInfo.cs
- SecurityToken.cs
- SpeechDetectedEventArgs.cs
- XmlDeclaration.cs
- ExceptionUtility.cs
- DataGridSortCommandEventArgs.cs
- ActivityMarkupSerializationProvider.cs
- EncoderParameter.cs
- TemplateBindingExtension.cs
- IdnElement.cs
- ReaderWriterLock.cs
- SaveFileDialog.cs
- LinearGradientBrush.cs
- MachineKeyValidationConverter.cs
- PropertyDescriptors.cs
- WebResponse.cs
- EdmValidator.cs
- DataGridViewSortCompareEventArgs.cs
- ProtocolsConfiguration.cs
- QueryPageSettingsEventArgs.cs
- LineSegment.cs
- BorderGapMaskConverter.cs
- PrinterUnitConvert.cs
- TreeChangeInfo.cs
- PreviewControlDesigner.cs
- RowsCopiedEventArgs.cs
- DesignerAttribute.cs
- DragEvent.cs
- Utils.cs
- GeometryValueSerializer.cs
- QilPatternVisitor.cs
- Binding.cs