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
- RichTextBoxAutomationPeer.cs
- CustomWebEventKey.cs
- SkewTransform.cs
- TraceXPathNavigator.cs
- Completion.cs
- SqlCacheDependencyDatabase.cs
- GAC.cs
- DependencyPropertyAttribute.cs
- MediaPlayerState.cs
- CollectionAdapters.cs
- ParseNumbers.cs
- DeclaredTypeValidatorAttribute.cs
- XslAst.cs
- Base64WriteStateInfo.cs
- VirtualPathData.cs
- PolicyException.cs
- AnnotationResource.cs
- ResourceIDHelper.cs
- DoubleAnimationClockResource.cs
- TreeViewHitTestInfo.cs
- EncoderFallback.cs
- IteratorDescriptor.cs
- SystemPens.cs
- UIElement3D.cs
- KeyBinding.cs
- IdentityReference.cs
- TraceHwndHost.cs
- SmtpReplyReaderFactory.cs
- EntityFrameworkVersions.cs
- ResXBuildProvider.cs
- RuntimeIdentifierPropertyAttribute.cs
- LifetimeServices.cs
- ReachBasicContext.cs
- UpdatePanelControlTrigger.cs
- ModuleConfigurationInfo.cs
- counter.cs
- ValidationEventArgs.cs
- CheckBoxRenderer.cs
- FixedSchema.cs
- StreamWriter.cs
- SqlDataSourceQueryEditorForm.cs
- GroupDescription.cs
- ADMembershipUser.cs
- securitycriticaldataClass.cs
- SqlClientMetaDataCollectionNames.cs
- PointLightBase.cs
- ExtenderProvidedPropertyAttribute.cs
- ThrowHelper.cs
- AppDomain.cs
- NoneExcludedImageIndexConverter.cs
- XmlQueryCardinality.cs
- FeatureSupport.cs
- assertwrapper.cs
- DynamicPropertyHolder.cs
- HierarchicalDataBoundControlAdapter.cs
- ActivityDefaults.cs
- PartBasedPackageProperties.cs
- HttpProfileBase.cs
- MethodRental.cs
- MultipleViewProviderWrapper.cs
- ThreadAbortException.cs
- WebPartConnectionsCancelEventArgs.cs
- _FtpDataStream.cs
- XamlToRtfWriter.cs
- RectAnimationBase.cs
- ParagraphResult.cs
- ImageAutomationPeer.cs
- XhtmlTextWriter.cs
- InternalRelationshipCollection.cs
- AsymmetricSignatureDeformatter.cs
- TextRunProperties.cs
- EtwTrace.cs
- CompilationUnit.cs
- X509Chain.cs
- ProxyHwnd.cs
- SqlUtils.cs
- DrawingCollection.cs
- OrderedDictionary.cs
- TypeConverterAttribute.cs
- ProfileProvider.cs
- StyleHelper.cs
- ParameterReplacerVisitor.cs
- Paragraph.cs
- FixedSOMPage.cs
- ExtendedTransformFactory.cs
- DynamicResourceExtensionConverter.cs
- RegexWriter.cs
- ValueOfAction.cs
- RegisteredExpandoAttribute.cs
- Wildcard.cs
- RegexGroup.cs
- XpsPackagingPolicy.cs
- TextDecoration.cs
- SQLSingleStorage.cs
- _BasicClient.cs
- SimpleBitVector32.cs
- Win32PrintDialog.cs
- InternalTypeHelper.cs
- RoleService.cs
- LoginAutoFormat.cs