Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Actions / DynamicMetaObjectBinder.cs / 1305376 / DynamicMetaObjectBinder.cs
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions; using System.Linq.Expressions.Compiler; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #else using System.Runtime.Remoting; #endif namespace System.Dynamic { ////// The dynamic call site binder that participates in the ///binding protocol. /// /// The public abstract class DynamicMetaObjectBinder : CallSiteBinder { #region Public APIs ///performs the binding of the dynamic operation using the runtime values /// as input. On the other hand, the participates in the /// binding protocol. /// /// Initializes a new instance of the protected DynamicMetaObjectBinder() { } ///class. /// /// The result type of the operation. /// public virtual Type ReturnType { get { return typeof(object); } } ////// Performs the runtime binding of the dynamic operation on a set of arguments. /// /// An array of arguments to the dynamic operation. /// The array ofinstances that represent the parameters of the call site in the binding process. /// A LabelTarget used to return the result of the dynamic binding. /// /// An Expression that performs tests on the dynamic operation arguments, and /// performs the dynamic operation if hte tests are valid. If the tests fail on /// subsequent occurrences of the dynamic operation, Bind will be called again /// to produce a new public sealed override Expression Bind(object[] args, ReadOnlyCollectionfor the new argument types. /// parameters, LabelTarget returnLabel) { ContractUtils.RequiresNotNull(args, "args"); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNull(returnLabel, "returnLabel"); if (args.Length == 0) { throw Error.OutOfRange("args.Length", 1); } if (parameters.Count == 0) { throw Error.OutOfRange("parameters.Count", 1); } if (args.Length != parameters.Count) { throw new ArgumentOutOfRangeException("args"); } // Ensure that the binder's ReturnType matches CallSite's return // type. We do this so meta objects and language binders can // compose trees together without needing to insert converts. Type expectedResult; if (IsStandardBinder) { expectedResult = ReturnType; if (returnLabel.Type != typeof(void) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, expectedResult)) { throw Error.BinderNotCompatibleWithCallSite(expectedResult, this, returnLabel.Type); } } else { // Even for non-standard binders, we have to at least make sure // it works with the CallSite's type to build the return. expectedResult = returnLabel.Type; } DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]); DynamicMetaObject[] metaArgs = CreateArgumentMetaObjects(args, parameters); DynamicMetaObject binding = Bind(target, metaArgs); if (binding == null) { throw Error.BindingCannotBeNull(); } Expression body = binding.Expression; BindingRestrictions restrictions = binding.Restrictions; // Ensure the result matches the expected result type. if (expectedResult != typeof(void) && !TypeUtils.AreReferenceAssignable(expectedResult, body.Type)) { // // Blame the last person that handled the result: assume it's // the dynamic object (if any), otherwise blame the language. // if (target.Value is IDynamicMetaObjectProvider) { throw Error.DynamicObjectResultNotAssignable(body.Type, target.Value.GetType(), this, expectedResult); } else { throw Error.DynamicBinderResultNotAssignable(body.Type, this, expectedResult); } } // if the target is IDO, standard binders ask it to bind the rule so we may have a target-specific binding. // it makes sense to restrict on the target's type in such cases. // ideally IDO metaobjects should do this, but they often miss that type of "this" is significant. if (IsStandardBinder && args[0] as IDynamicMetaObjectProvider != null) { if (restrictions == BindingRestrictions.Empty) { throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this); } } restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters); // Add the return if (body.NodeType != ExpressionType.Goto) { body = Expression.Return(returnLabel, body); } // Finally, add restrictions if (restrictions != BindingRestrictions.Empty) { body = Expression.IfThen(restrictions.ToExpression(), body); } return body; } private static DynamicMetaObject[] CreateArgumentMetaObjects(object[] args, ReadOnlyCollection parameters) { DynamicMetaObject[] mos; if (args.Length != 1) { mos = new DynamicMetaObject[args.Length - 1]; for (int i = 1; i < args.Length; i++) { mos[i - 1] = DynamicMetaObject.Create(args[i], parameters[i]); } } else { mos = DynamicMetaObject.EmptyMetaObjects; } return mos; } private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection parameters) { #if !SILVERLIGHT for (int i = 0; i < parameters.Count; i++) { var expr = parameters[i]; var value = args[i] as MarshalByRefObject; // special case for MBR objects. // when MBR objects are remoted they can have different conversion behavior // so bindings created for local and remote objects should not be mixed. if (value != null && !IsComObject(value)) { BindingRestrictions remotedRestriction; if (RemotingServices.IsObjectOutOfAppDomain(value)) { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ); } else { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Not( Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ) ); } restrictions = restrictions.Merge(remotedRestriction); } } #endif return restrictions; } /// /// When overridden in the derived class, performs the binding of the dynamic operation. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public abstract DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args); ///representing the result of the binding. /// Gets an expression that will cause the binding to be updated. It /// indicates that the expression's binding is no longer valid. /// This is typically used when the "version" of a dynamic object has /// changed. /// /// TheType property of the resulting expression; any type is allowed. ///The update expression. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] public Expression GetUpdateExpression(Type type) { return Expression.Goto(CallSiteBinder.UpdateLabel, type); } ////// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNull(target, "target"); if (args == null) { return MakeDeferred(target.Restrictions, target); } else { return MakeDeferred( target.Restrictions.Merge(BindingRestrictions.Combine(args)), args.AddFirst(target) ); } } ///representing the result of the binding. /// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(params DynamicMetaObject[] args) { return MakeDeferred(BindingRestrictions.Combine(args), args); } private DynamicMetaObject MakeDeferred(BindingRestrictions rs, params DynamicMetaObject[] args) { var exprs = DynamicMetaObject.GetExpressions(args); Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, ReturnType); // Because we know the arguments match the delegate type (we just created the argument types) // we go directly to DynamicExpression.Make to avoid a bunch of unnecessary argument validation return new DynamicMetaObject( DynamicExpression.Make(ReturnType, delegateType, this, new TrueReadOnlyCollectionrepresenting the result of the binding. (exprs)), rs ); } #endregion // used to detect standard MetaObjectBinders. internal virtual bool IsStandardBinder { get { return false; } } #if !SILVERLIGHT private static readonly Type ComObjectType = typeof(object).Assembly.GetType("System.__ComObject"); private static bool IsComObject(object obj) { // we can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust return obj != null && ComObjectType.IsAssignableFrom(obj.GetType()); } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions; using System.Linq.Expressions.Compiler; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #else using System.Runtime.Remoting; #endif namespace System.Dynamic { /// /// The dynamic call site binder that participates in the ///binding protocol. /// /// The public abstract class DynamicMetaObjectBinder : CallSiteBinder { #region Public APIs ///performs the binding of the dynamic operation using the runtime values /// as input. On the other hand, the participates in the /// binding protocol. /// /// Initializes a new instance of the protected DynamicMetaObjectBinder() { } ///class. /// /// The result type of the operation. /// public virtual Type ReturnType { get { return typeof(object); } } ////// Performs the runtime binding of the dynamic operation on a set of arguments. /// /// An array of arguments to the dynamic operation. /// The array ofinstances that represent the parameters of the call site in the binding process. /// A LabelTarget used to return the result of the dynamic binding. /// /// An Expression that performs tests on the dynamic operation arguments, and /// performs the dynamic operation if hte tests are valid. If the tests fail on /// subsequent occurrences of the dynamic operation, Bind will be called again /// to produce a new public sealed override Expression Bind(object[] args, ReadOnlyCollectionfor the new argument types. /// parameters, LabelTarget returnLabel) { ContractUtils.RequiresNotNull(args, "args"); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNull(returnLabel, "returnLabel"); if (args.Length == 0) { throw Error.OutOfRange("args.Length", 1); } if (parameters.Count == 0) { throw Error.OutOfRange("parameters.Count", 1); } if (args.Length != parameters.Count) { throw new ArgumentOutOfRangeException("args"); } // Ensure that the binder's ReturnType matches CallSite's return // type. We do this so meta objects and language binders can // compose trees together without needing to insert converts. Type expectedResult; if (IsStandardBinder) { expectedResult = ReturnType; if (returnLabel.Type != typeof(void) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, expectedResult)) { throw Error.BinderNotCompatibleWithCallSite(expectedResult, this, returnLabel.Type); } } else { // Even for non-standard binders, we have to at least make sure // it works with the CallSite's type to build the return. expectedResult = returnLabel.Type; } DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]); DynamicMetaObject[] metaArgs = CreateArgumentMetaObjects(args, parameters); DynamicMetaObject binding = Bind(target, metaArgs); if (binding == null) { throw Error.BindingCannotBeNull(); } Expression body = binding.Expression; BindingRestrictions restrictions = binding.Restrictions; // Ensure the result matches the expected result type. if (expectedResult != typeof(void) && !TypeUtils.AreReferenceAssignable(expectedResult, body.Type)) { // // Blame the last person that handled the result: assume it's // the dynamic object (if any), otherwise blame the language. // if (target.Value is IDynamicMetaObjectProvider) { throw Error.DynamicObjectResultNotAssignable(body.Type, target.Value.GetType(), this, expectedResult); } else { throw Error.DynamicBinderResultNotAssignable(body.Type, this, expectedResult); } } // if the target is IDO, standard binders ask it to bind the rule so we may have a target-specific binding. // it makes sense to restrict on the target's type in such cases. // ideally IDO metaobjects should do this, but they often miss that type of "this" is significant. if (IsStandardBinder && args[0] as IDynamicMetaObjectProvider != null) { if (restrictions == BindingRestrictions.Empty) { throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this); } } restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters); // Add the return if (body.NodeType != ExpressionType.Goto) { body = Expression.Return(returnLabel, body); } // Finally, add restrictions if (restrictions != BindingRestrictions.Empty) { body = Expression.IfThen(restrictions.ToExpression(), body); } return body; } private static DynamicMetaObject[] CreateArgumentMetaObjects(object[] args, ReadOnlyCollection parameters) { DynamicMetaObject[] mos; if (args.Length != 1) { mos = new DynamicMetaObject[args.Length - 1]; for (int i = 1; i < args.Length; i++) { mos[i - 1] = DynamicMetaObject.Create(args[i], parameters[i]); } } else { mos = DynamicMetaObject.EmptyMetaObjects; } return mos; } private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection parameters) { #if !SILVERLIGHT for (int i = 0; i < parameters.Count; i++) { var expr = parameters[i]; var value = args[i] as MarshalByRefObject; // special case for MBR objects. // when MBR objects are remoted they can have different conversion behavior // so bindings created for local and remote objects should not be mixed. if (value != null && !IsComObject(value)) { BindingRestrictions remotedRestriction; if (RemotingServices.IsObjectOutOfAppDomain(value)) { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ); } else { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Not( Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ) ); } restrictions = restrictions.Merge(remotedRestriction); } } #endif return restrictions; } /// /// When overridden in the derived class, performs the binding of the dynamic operation. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public abstract DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args); ///representing the result of the binding. /// Gets an expression that will cause the binding to be updated. It /// indicates that the expression's binding is no longer valid. /// This is typically used when the "version" of a dynamic object has /// changed. /// /// TheType property of the resulting expression; any type is allowed. ///The update expression. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] public Expression GetUpdateExpression(Type type) { return Expression.Goto(CallSiteBinder.UpdateLabel, type); } ////// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNull(target, "target"); if (args == null) { return MakeDeferred(target.Restrictions, target); } else { return MakeDeferred( target.Restrictions.Merge(BindingRestrictions.Combine(args)), args.AddFirst(target) ); } } ///representing the result of the binding. /// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(params DynamicMetaObject[] args) { return MakeDeferred(BindingRestrictions.Combine(args), args); } private DynamicMetaObject MakeDeferred(BindingRestrictions rs, params DynamicMetaObject[] args) { var exprs = DynamicMetaObject.GetExpressions(args); Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, ReturnType); // Because we know the arguments match the delegate type (we just created the argument types) // we go directly to DynamicExpression.Make to avoid a bunch of unnecessary argument validation return new DynamicMetaObject( DynamicExpression.Make(ReturnType, delegateType, this, new TrueReadOnlyCollectionrepresenting the result of the binding. (exprs)), rs ); } #endregion // used to detect standard MetaObjectBinders. internal virtual bool IsStandardBinder { get { return false; } } #if !SILVERLIGHT private static readonly Type ComObjectType = typeof(object).Assembly.GetType("System.__ComObject"); private static bool IsComObject(object obj) { // we can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust return obj != null && ComObjectType.IsAssignableFrom(obj.GetType()); } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- JpegBitmapDecoder.cs
- Internal.cs
- XmlSchemaValidationException.cs
- EncoderReplacementFallback.cs
- Font.cs
- ServiceOperationListItem.cs
- BamlCollectionHolder.cs
- FlowPanelDesigner.cs
- ItemsControl.cs
- PermissionSetEnumerator.cs
- IPAddressCollection.cs
- PermissionSetEnumerator.cs
- DNS.cs
- EntityDataSourceWrapperCollection.cs
- EncryptedType.cs
- ProviderCollection.cs
- SslStream.cs
- MenuItemStyle.cs
- GPPOINT.cs
- ImageCodecInfoPrivate.cs
- CacheMemory.cs
- TreeNodeSelectionProcessor.cs
- VarRefManager.cs
- ColumnProvider.cs
- BrowserDefinitionCollection.cs
- XsltQilFactory.cs
- PersistChildrenAttribute.cs
- TransformDescriptor.cs
- CounterCreationDataConverter.cs
- ContentValidator.cs
- ISAPIApplicationHost.cs
- __ComObject.cs
- Size3DConverter.cs
- MemberProjectionIndex.cs
- DateTimeOffsetAdapter.cs
- WebPartZoneBase.cs
- MessageEnumerator.cs
- RadioButtonRenderer.cs
- GridViewRow.cs
- MimeWriter.cs
- WebProxyScriptElement.cs
- FragmentNavigationEventArgs.cs
- QueueProcessor.cs
- TraceXPathNavigator.cs
- CompilerErrorCollection.cs
- LabelEditEvent.cs
- HttpCachePolicyWrapper.cs
- DataGridViewLinkCell.cs
- XhtmlConformanceSection.cs
- ByteRangeDownloader.cs
- AssociationEndMember.cs
- BindingNavigator.cs
- DataControlLinkButton.cs
- DeviceContexts.cs
- SystemWebCachingSectionGroup.cs
- MenuItemBindingCollection.cs
- EventProviderTraceListener.cs
- Soap.cs
- SmiSettersStream.cs
- DataViewListener.cs
- BookmarkEventArgs.cs
- ProfileProvider.cs
- Size3DConverter.cs
- IdentityReference.cs
- CustomErrorsSection.cs
- DataObjectPastingEventArgs.cs
- QueryOutputWriter.cs
- DayRenderEvent.cs
- Propagator.Evaluator.cs
- UserControlParser.cs
- OrderByExpression.cs
- controlskin.cs
- DbConnectionHelper.cs
- DescendantBaseQuery.cs
- ObjectListSelectEventArgs.cs
- UrlMapping.cs
- Action.cs
- TimeSpanValidator.cs
- FacetChecker.cs
- ToolStripCodeDomSerializer.cs
- LinkConverter.cs
- XmlTextReaderImpl.cs
- embossbitmapeffect.cs
- ExpressionNode.cs
- DateTimeConverter.cs
- Property.cs
- XmlSchemaSimpleContentExtension.cs
- CodeMethodReturnStatement.cs
- VerificationException.cs
- MsmqHostedTransportManager.cs
- __Error.cs
- WebEventTraceProvider.cs
- DbDataRecord.cs
- PixelFormats.cs
- XamlNamespaceHelper.cs
- DelegatingConfigHost.cs
- DataControlLinkButton.cs
- HttpApplication.cs
- TreeNodeMouseHoverEvent.cs
- CompositionTarget.cs